<template>
  <div class="arpe-container">
    <!-- Header -->
    <div class="arpe-header">
      <div class="arpe-title">酸轧生产效率监控</div>
    </div>
    <div class="arpe-content-layout">
      <!-- 左侧钢卷列 -->
      <div class="arpe-side-rolls arpe-side-rolls-left">
        <div v-for="(img, idx) in leftRolls" :key="'left-roll-' + idx" class="arpe-roll-img-wrap">
          <img :src="img" class="arpe-roll-img" />
        </div>
      </div>
      <!-- 主体内容区 -->
      <div class="arpe-main">
        <!-- 新增：顶部自定义行 -->
        <div class="svg-area" style="position: relative; min-height: 180px; margin-top: 70px">
          <!-- 绝对定位的仪表盘卡片组 -->
          <div class="arpe-gauge-abs-group" style="position: relative; width: 100%; z-index: 10">
            <!-- 出口段：仪表盘 + AI设定值 成对联动 -->
            <div class="arpe-pair" style="position: absolute; left: -30px; top: -90px; display: flex; align-items: center; gap: 10px">
              <div class="arpe-gauge-wrap" style="position: static">
                <div id="gauge-skinpass" class="gauge-container gauge-skinpass"></div>
              </div>
              <div class="arpe-ai-set-card" style="position: static">
                <div class="arpe-ai-set-card-status">
                  <span v-if="millAIMode === 0" class="ai-mode-badge ai-mode-off">未启用</span>
                  <span v-else-if="millAIMode === 1" class="ai-mode-badge ai-mode-on">已启用</span>
                </div>
                <div class="arpe-ai-set-card-title">出口段AI设定值</div>
                <div class="arpe-ai-set-card-value">{{ exportSetValue }} <span class="arpe-ai-set-card-unit">m/min</span></div>
              </div>
            </div>

            <!-- 新增：轧机入口速度小卡片（取 L_AGC_STRIPSFB0，取整） -->
            <!-- <div class="arpe-small-info-card" style="position: absolute; left: 430px; top: 20px;">
              <div class="arpe-small-info-title">轧机入口速度</div>
              <div class="arpe-small-info-value">{{ entrySpeedFb }} <span class="unit">m/min</span></div>
            </div> -->

            <!-- 新增：TCM速度仪表盘 -->
            <div class="arpe-gauge-wrap" style="position: absolute; left: 400px; top: -90px">
              <div id="gauge-tcm" class="gauge-container gauge-tcm"></div>
            </div>

            <!-- 焊机仪表盘（保持原有独立） -->
            <div class="arpe-gauge-wrap" style="position: absolute; left: 550px; top: -90px; /* 修改这里可调整焊机仪表盘位置 */">
              <div id="gauge-welder" class="gauge-container gauge-welder"></div>
            </div>
            <!-- 温度条（单独调整位置：left/top） -->
            <!-- <div class="arpe-temp-bar-group-center" style="position: absolute; left: 780px; top: 15px; /* 修改这里可调整温度条位置 */">
              <div class="arpe-temp-bar-item-inline">
                <div class="arpe-temp-bar-label-inline">3#</div>
                <div class="arpe-temp-bar-outer-inline">
                  <div class="arpe-temp-bar-inner-inline" :style="{ height: '83%' }"></div>
                </div>
                <div class="arpe-temp-bar-value-inline">{{ leftemperature }}℃</div>
              </div>
              <div class="arpe-temp-bar-item-inline">
                <div class="arpe-temp-bar-label-inline">2#</div>
                <div class="arpe-temp-bar-outer-inline">
                  <div class="arpe-temp-bar-inner-inline" :style="{ height: '83%' }"></div>
                </div>
                <div class="arpe-temp-bar-value-inline">{{ Intertemperature }}℃</div>
              </div>
              <div class="arpe-temp-bar-item-inline">
                <div class="arpe-temp-bar-label-inline">1#</div>
                <div class="arpe-temp-bar-outer-inline">
                  <div class="arpe-temp-bar-inner-inline" :style="{ height: '83%' }"></div>
                </div>
                <div class="arpe-temp-bar-value-inline">{{ righttemperature }}℃</div>
              </div>
            </div> -->
            <!-- 工艺段：仪表盘 + AI设定值 成对联动 -->
            <div class="arpe-pair" style="position: absolute; right: 560px; top: -90px; display: flex; align-items: center; gap: 10px">
              <div class="arpe-gauge-wrap" style="position: static">
                <div id="gauge-process" class="gauge-container gauge-process"></div>
                <div class="arpe-gauge-label"></div>
              </div>
              <div class="arpe-ai-set-card" style="position: static">
                <div class="arpe-ai-set-card-status">
                  <span v-if="processAIMode === 0" class="ai-mode-badge ai-mode-off">未启用</span>
                  <span v-else-if="processAIMode === 1" class="ai-mode-badge ai-mode-on">已启用</span>
                </div>
                <div class="arpe-ai-set-card-title">工艺段AI设定值</div>
                <div class="arpe-ai-set-card-value">{{ processSetValue }} <span class="arpe-ai-set-card-unit">m/min</span></div>
              </div>
            </div>

            <!-- 入口段：AI设定值 + 仪表盘 成对联动 -->
            <div class="arpe-pair" style="position: absolute; right: -60px; top: -90px; display: flex; align-items: center; gap: 10px">
              <div class="arpe-ai-set-card" style="position: static; z-index: 11">
                <div class="arpe-ai-set-card-status">
                  <span v-if="entryAIMode === 0" class="ai-mode-badge ai-mode-off">未启用</span>
                  <span v-else-if="entryAIMode === 1" class="ai-mode-badge ai-mode-on">已启用</span>
                </div>
                <div class="arpe-ai-set-card-title">入口段AI设定值</div>
                <div class="arpe-ai-set-card-value">{{ entrySetValue }} <span class="arpe-ai-set-card-unit">m/min</span></div>
              </div>
              <div class="arpe-gauge-wrap" style="position: static; z-index: 10">
                <div id="gauge-entry" class="gauge-container gauge-entry"></div>
              </div>
            </div>
            <!-- 上压力/下压力卡片（单独调整位置：right/top） -->
            <!-- <div
              class="arpe-ds-card arpe-ds-card-right"
              style="position: absolute; right: 150px; top: -90px; /* 修改这里可调整上压力/下压力卡片位置 */"
            >
              <div class="arpe-ds-row"><span class="arpe-ds-label">上压力</span> <span class="arpe-ds-value">1.23%</span></div>
              <div class="arpe-ds-row"><span class="arpe-ds-label">下压力</span> <span class="arpe-ds-value">1.24%</span></div>
            </div> -->
            <!-- 新增两个ref变量用于显示开卷机剩余长度 -->
            <div class="arpe-ai-set-card2" style="position: absolute; right: -50px; top: 25px">
              <div class="arpe-ai-set-card-title">{{ por1CoilNo }} <br />开卷机剩余长度</div>
              <div class="arpe-ai-set-card-value">{{ por1Len }} <span class="arpe-ai-set-card-unit">m</span></div>
            </div>
            <div class="arpe-ai-set-card2" style="position: absolute; right: -50px; top: 100px">
              <div class="arpe-ai-set-card-title">{{ por2CoilNo }} <br />开卷机剩余度</div>
              <div class="arpe-ai-set-card-value">{{ por2Len }} <span class="arpe-ai-set-card-unit">m</span></div>
            </div>
          </div>
          <!-- SVG 图 -->
          <div ref="svgContainer" style="height: 100%; width: 100%; position: relative">
            <svg-load :name="technologicalName" style="z-index: 999; height: 100%; width: 100%"></svg-load>
            <!-- 新增：右侧两个小卡片，显示por1CoilNo和por2CoilNo -->
            <!-- <div v-if="por1CoilNo" class="coilno-card coilno-card-1">1#{{ por1CoilNo }}</div>
            <div v-if="por2CoilNo" class="coilno-card coilno-card-2">2#{{ por2CoilNo }}</div> -->
          </div>
          <el-row class="coilInfo">
            <el-col :span="8" class="coilInfo-item" v-if="coilInfoDataLeft[0]?.entid != ''">
              <el-table :data="coilInfoDataLeft" size="small" :show-header="false" :cell-style="getColors(coilIds?.coilIds?.[2])">
                <el-table-column prop="entid" min-width="120px" />
                <el-table-column prop="steelGrade" min-width="130px" />
                <el-table-column prop="ys" width="60px" />
                <el-table-column prop="hotThkAim" width="60px" />
                <el-table-column prop="hotFlatMin" width="60px" />
                <el-table-column prop="outMatMaxThick" width="60px" />
                <el-table-column prop="outMatWidth" width="60px" />
              </el-table>
            </el-col>
            <el-col :span="8" v-if="coilInfoDataMiddle[0]?.entid != ''">
              <el-table :data="coilInfoDataMiddle" size="small" :show-header="false" :cell-style="getColors(coilIds?.coilIds?.[1])">
                <el-table-column prop="entid" min-width="120px" />
                <el-table-column prop="steelGrade" min-width="130px" />
                <el-table-column prop="ys" width="60px" />
                <el-table-column prop="hotThkAim" width="60px" />
                <el-table-column prop="hotFlatMin" width="60px" />
                <el-table-column prop="outMatMaxThick" width="60px" />
                <el-table-column prop="outMatWidth" width="60px" />
              </el-table>
            </el-col>
            <el-col :span="8" v-if="coilInfoDataRight[0]?.entid != ''">
              <el-table :data="coilInfoDataRight" size="small" :show-header="false" :cell-style="getColors(coilIds?.coilIds?.[0])">
                <el-table-column prop="entid" min-width="120px" />
                <el-table-column prop="steelGrade" min-width="130px" />
                <el-table-column prop="ys" width="60px" />
                <el-table-column prop="hotThkAim" width="60px" />
                <el-table-column prop="hotFlatMin" width="60px" />
                <el-table-column prop="outMatMaxThick" width="60px" />
                <el-table-column prop="outMatWidth" width="60px" />
              </el-table>
            </el-col>
          </el-row>
          <!-- <InlineSvgWithHotspot src="/src/assets/images/szxl/xl2280.svg" :hotspotInfo="svgHotspotInfo" style="width: 100%; height: 20vh" /> -->
        </div>
        <!-- 第二行：进度条与卷号区 -->
        <div class="arpe-row arpe-row-progress" style="height: 54px; position: relative; z-index: 2">
          <!-- 悬浮卡片，默认隐藏，悬浮到区段时显示 -->
          <div
            v-if="hoveredSegmentIndex !== null && progressSegments[hoveredSegmentIndex]"
            style="
              position: absolute;
              left: 50%;
              top: -64px;
              transform: translateX(-50%);
              z-index: 10;
              min-width: 320px;
              min-height: 38px;
              background: rgba(0, 24, 48, 0.92);
              border-radius: 14px;
              box-shadow: 0 0 18px #00eaff55;
              padding: 14px 38px;
              display: flex;
              flex-direction: column;
              align-items: center;
              justify-content: center;
              font-size: 15px;
              color: #fff;
              font-weight: 500;
              letter-spacing: 1px;
              text-shadow:
                0 0 8px #00eaff,
                0 0 2px #000;
              border: 1.5px solid #00eaff66;
              backdrop-filter: blur(4px);
            "
          >
            <div style="font-size: 16px; font-weight: bold; margin-bottom: 4px">{{ progressSegments[hoveredSegmentIndex].label }}信息</div>
            <div>卷号：{{ progressSegments[hoveredSegmentIndex].coilId || '-' }}</div>
            <div>区段类型：{{ progressSegments[hoveredSegmentIndex].label }}</div>
            <div>状态：运行中</div>
            <!-- 可根据实际数据补充更多字段 -->
          </div>
          <div class="arpe-progress-bar-area" style="height: 54px">
            <div class="arpe-progress-bar-flex" style="gap: 0; height: 100%">
              <div
                v-for="(seg, idx) in progressSegments"
                :key="idx"
                class="arpe-bar-rect arpe-bar-rect-merged"
                :style="{
                  flex: seg.percent,
                  background: seg.color,
                  borderRadius: '0',
                  margin: '0',
                  minWidth: '0',
                  opacity: 0.78,
                  position: 'relative',
                  overflow: 'hidden',
                  backdropFilter: 'blur(2px)',
                  height: '100%',
                }"
                @mouseenter="handleSegmentMouseEnter(idx)"
                @mouseleave="handleSegmentMouseLeave"
              >
                <!-- 不再直接显示卷号等信息 -->
              </div>
            </div>
          </div>
        </div>
        <!-- 第三行：图表区 -->
        <div class="arpe-row arpe-row-charts">
          <div class="arpe-chart-group">
            <!-- 雷达图1 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">雷达图标题</div>
              <div id="radar1" class="arpe-chart"></div>
              <div class="arpe-chart-legend" style="font-size: 12px; text-align: center; margin-top: 2px; letter-spacing: 2px">
                set1#:%&nbsp;&nbsp;set2#:%&nbsp;&nbsp;set3#:%
              </div>
            </div>
            <!-- 雷达图2 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">雷达图标题</div>
              <div id="radar2" class="arpe-chart"></div>
              <div class="arpe-chart-legend">
                <span class="legend-dot legend-dot-blue"></span>Data 1 <span class="legend-dot legend-dot-green"></span>Data 2
              </div>
            </div>
            <!-- 环形图1 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">圆盘剪时序跟踪</div>
              <div id="pie1" class="arpe-chart"></div>
            </div>
            <!-- 雷达图3 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">雷达图标题</div>
              <div id="radar3" class="arpe-chart"></div>
              <div class="arpe-chart-legend">
                <span class="legend-dot legend-dot-blue"></span>Data 1 <span class="legend-dot legend-dot-green"></span>Data 2
              </div>
            </div>
            <!-- 柱状图 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">活套套量</div>
              <div id="bar1" class="arpe-chart"></div>
              <!-- 新增：最大设定值显示 -->
              <div
                class="arpe-chart-legend"
                style="
                  font-size: 13px;
                  text-align: left;
                  margin-top: 2px;
                  letter-spacing: 2px;
                  display: flex;
                  align-items: center;
                  justify-content: flex-start;
                "
              >
                <span style="color: #00eaff; font-weight: bold; margin-right: 12px">最大设定值:</span>
                <span style="color: #fff; font-size: 15px; font-weight: bold; flex: 1; text-align: center">
                  {{ exportLooperMaxSet }}&nbsp;&nbsp;&nbsp;&nbsp;{{ middleLooperMaxSet }}&nbsp;&nbsp;&nbsp;&nbsp;{{ inletLooperMaxSet }}
                </span>
              </div>
              <!-- 原有set: % % %可保留或去除 -->
              <!-- <div class="arpe-chart-legend" style="font-size: 15px; text-align: left; margin-top: 2px; letter-spacing: 2px; display: flex; align-items: center; justify-content: flex-start;">
                <span style="color:#00eaff;font-weight:bold;margin-right:12px;">set:</span>
                <span style="color:#fff;font-size:18px;font-weight:bold;flex:1;text-align:center;">%&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;%</span>
              </div> -->
            </div>
            <!-- 环形图2 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">焊机时序跟踪</div>
              <div id="pie2" class="arpe-chart"></div>
              <!-- 焊机时序跟踪卷号显示 -->
              <div class="arpe-chart-coilno" v-if="welderCoilNo">
                {{ welderCoilNo }}
              </div>
            </div>
            <!-- 环形图3 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">2#开卷机时序跟踪</div>
              <div id="pie3" class="arpe-chart"></div>
              <!-- 2#开卷机时序跟踪卷号显示 -->
              <div class="arpe-chart-coilno" v-if="por2CoilNo">
                {{ por2CoilNo }}
              </div>
            </div>
            <!-- 环形图4 -->
            <div class="arpe-chart-block">
              <div class="arpe-chart-title">1#开卷机时序跟踪</div>
              <div id="pie4" class="arpe-chart"></div>
              <!-- 1#开卷机时序跟踪卷号显示 -->
              <div class="arpe-chart-coilno" v-if="por1CoilNo">
                {{ por1CoilNo }}
              </div>
            </div>
          </div>
        </div>
        <!-- 新增：第五行上方预留一行 -->
        <div class="arpe-row arpe-row-custom-top">
          <div class="arpe-alert-box arpe-alert-box-left">
            <template v-if="exportWarningFirst">
              <span
                style="
                  color: #fff;
                  font-size: 0.62em;
                  max-width: 92%;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                  display: inline-block;
                  vertical-align: middle;
                "
                >{{ formatWarningText(exportWarningFirst) }}</span
              >
              <template v-if="exportWarningRest.length">
                <el-dropdown trigger="click">
                  <span style="color: #00eaff; cursor: pointer; margin-left: 8px; font-size: 0.82em">更多</span>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item v-for="(item, idx) in exportWarnings" :key="idx" @click.native="handleExportWarningSelect(idx)">
                        <span
                          style="
                            color: #111;
                            font-size: 0.82em;
                            max-width: 220px;
                            overflow: hidden;
                            text-overflow: ellipsis;
                            white-space: nowrap;
                            display: inline-block;
                            vertical-align: middle;
                          "
                          >{{ formatWarningText(item) }}</span
                        >
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </template>
            </template>
          </div>
          <div class="arpe-alert-box arpe-alert-box-middle">
            <span
              style="
                color: #fff;
                font-size: 0.8em;
                max-width: 92%;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                display: inline-block;
                vertical-align: middle;
              "
              >{{ formatWarningText(processWarningFirst) }}</span
            >
            <template v-if="processWarningRest.length">
              <el-dropdown trigger="click">
                <span style="color: #00eaff; cursor: pointer; margin-left: 8px; font-size: 0.82em">更多</span>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item v-for="(item, idx) in processWarnings" :key="idx" @click.native="handleProcessWarningSelect(idx)">
                      <span
                        style="
                          color: #111;
                          font-size: 0.82em;
                          max-width: 220px;
                          overflow: hidden;
                          text-overflow: ellipsis;
                          white-space: nowrap;
                          display: inline-block;
                          vertical-align: middle;
                        "
                        >{{ formatWarningText(item) }}</span
                      >
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </template>
          </div>
          <div class="arpe-alert-box arpe-alert-box-right">
            <span
              style="
                color: #fff;
                font-size: 0.8em;
                max-width: 92%;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                display: inline-block;
                vertical-align: middle;
              "
              >{{ formatWarningText(entryWarningFirst) }}</span
            >
            <template v-if="entryWarningRest.length">
              <el-dropdown trigger="click">
                <span style="color: #00eaff; cursor: pointer; margin-left: 8px; font-size: 0.82em">更多</span>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item v-for="(item, idx) in entryWarnings" :key="idx" @click.native="handleEntryWarningSelect(idx)">
                      <span
                        style="
                          color: #111;
                          font-size: 0.82em;
                          max-width: 220px;
                          overflow: hidden;
                          text-overflow: ellipsis;
                          white-space: nowrap;
                          display: inline-block;
                          vertical-align: middle;
                        "
                        >{{ formatWarningText(item) }}</span
                      >
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </template>
          </div>
        </div>
        <!-- 底部图表带：左侧生产效率监控图表，右侧原有图表 -->
        <div class="arpe-row arpe-row-bottom-graph">
          <!-- 新增：生产效率监控图表（移到最左侧） -->
          <div class="arpe-production-efficiency-chart">
            <div class="chart-header">
              <div class="chart-title-left">实时数据</div>
              <div class="chart-legend">
                <span class="legend-item"> <span class="legend-dot legend-dot-power"></span>功率实际值 </span>
                <span class="legend-item"> <span class="legend-dot legend-dot-torque"></span>电机扭矩实际值 </span>
              </div>
            </div>
            <div ref="productionEfficiencyChartRef" class="production-efficiency-chart__container"></div>
          </div>
          <!-- 新增：在预测产量柱形图左侧放置两个柱形图（内联样式，不改全局样式） -->
          <div
            style="
              width: 360px;
              min-width: 360px;
              height: 220px;
              display: grid;
              grid-template-columns: repeat(2, 1fr);
              grid-auto-rows: 1fr;
              gap: 12px;
              align-items: stretch;
              justify-items: stretch;
              margin-right: 68px;
            "
          >
            <div
              v-for="(item, idx) in statsCards"
              :key="'stat-' + idx"
              style="
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 6px;
                background: rgba(0, 24, 48, 0.25);
                border: 1px solid rgba(0, 246, 255, 0.25);
                border-radius: 10px;
                box-shadow: inset 0 0 12px rgba(0, 246, 255, 0.12);
                padding: 8px 6px;
              "
            >
              <div style="color: #b2eaff; font-size: 12px; letter-spacing: 1px">{{ item.label }}</div>
              <div style="color: #00eaff; font-size: 16px; font-weight: 700; text-shadow: 0 0 8px #00eaff">
                {{ item.value
                }}<span v-if="item.suffix" style="margin-left: 4px; font-size: 12px; color: #b2eaff; font-weight: 600">{{ item.suffix }}</span>
              </div>
            </div>
          </div>
          <div
            style="
              width: 170px;
              min-width: 170px;
              height: 220px;
              display: flex;
              align-items: flex-end;
              justify-content: center;
              gap: 18px;
              margin-right: 72px;
            "
          >
            <!-- 日计划下达产量 -->
            <div style="display: flex; flex-direction: column; align-items: center; gap: 8px">
              <div style="position: relative">
                <div
                  style="
                    width: 54px;
                    height: 170px;
                    border: 2px solid rgba(0, 234, 255, 0.6);
                    border-radius: 12px;
                    background: rgba(0, 24, 48, 0.35);
                    box-shadow: inset 0 0 14px rgba(0, 234, 255, 0.18);
                    padding: 4px;
                    display: flex;
                    align-items: flex-end;
                    justify-content: center;
                  "
                >
                  <div
                    :style="{
                      width: '100%',
                      height: Math.max(0, Math.min(100, dayPlanIssued)) + '%',
                      background: 'linear-gradient(180deg, rgba(0,246,255,0.95) 0%, rgba(0,246,255,0.35) 100%)',
                      borderRadius: '8px',
                      boxShadow: '0 0 10px rgba(0,246,255,0.35)',
                    }"
                  ></div>
                </div>
                <!-- 数值显示 -->
                <div
                  style="
                    position: absolute;
                    top: -25px;
                    left: 50%;
                    transform: translateX(-50%);
                    color: #00f6ff;
                    font-size: 14px;
                    font-weight: 700;
                    white-space: nowrap;
                    text-shadow: 0 0 8px rgba(0, 246, 255, 0.8);
                  "
                >
                  {{ dayPlanIssuedValue > 0 ? dayPlanIssuedValue.toFixed(0) : '0' }}
                </div>
              </div>
              <div style="color: #b2eaff; font-size: 12px; text-align: center; line-height: 1.2; width: 120px">日计划下达产量</div>
            </div>

            <!-- 日计划产量累计达成率 -->
            <div style="display: flex; flex-direction: column; align-items: center; gap: 8px">
              <div style="position: relative">
                <div
                  style="
                    width: 54px;
                    height: 170px;
                    border: 2px solid rgba(82, 196, 26, 0.6);
                    border-radius: 12px;
                    background: rgba(0, 24, 48, 0.35);
                    box-shadow: inset 0 0 14px rgba(82, 196, 26, 0.18);
                    padding: 4px;
                    display: flex;
                    align-items: flex-end;
                    justify-content: center;
                  "
                >
                  <div
                    :style="{
                      width: '100%',
                      height: Math.max(0, Math.min(100, dayPlanAchi)) + '%',
                      background: 'linear-gradient(180deg, rgba(82,196,26,0.95) 0%, rgba(82,196,26,0.35) 100%)',
                      borderRadius: '8px',
                      boxShadow: '0 0 10px rgba(82,196,26,0.35)',
                    }"
                  ></div>
                </div>
                <!-- 数值显示 -->
                <div
                  style="
                    position: absolute;
                    top: -25px;
                    left: 50%;
                    transform: translateX(-50%);
                    color: #52c41a;
                    font-size: 14px;
                    font-weight: 700;
                    white-space: nowrap;
                    text-shadow: 0 0 8px rgba(82, 196, 26, 0.8);
                  "
                >
                  {{ Math.round(dayPlanAchi) }}%
                </div>
              </div>
              <div style="color: #b2eaff; font-size: 12px; text-align: center; line-height: 1.2; width: 120px">日计划产量累计达成率</div>
            </div>
          </div>
          <div class="arpe-bottom-right-bar">
            <div class="bar-header">
              <el-radio-group v-model="millUnitDateType" size="small" @change="fetchMillUnitBarData">
                <el-radio-button label="hour">小时</el-radio-button>
                <el-radio-button label="day">天</el-radio-button>
              </el-radio-group>
            </div>
            <div ref="prodBarLineLocalRef" class="arpe-bottom-right-bar__chart"></div>
          </div>
        </div>
        <!-- 表格区 -->
        <div class="arpe-row-tables">
          <div class="arpe-tables-wrapper" ref="arpeTablesWrapperRef" :class="{ grabbing: isDragging }">
            <div class="arpe-table-container" v-for="(table, idx) in tableList" :key="'tb-' + idx">
              <div class="arpe-table-header">
                <div class="arpe-title-icon-left"></div>
                <span>{{ table.title }}</span>
                <div class="arpe-title-icon-right"></div>
              </div>
              <div class="arpe-table-content">
                <!-- 条件渲染：重焊统计表格 -->
                <el-table
                  v-if="table.title === '重焊统计'"
                  :data="reWeldTableData"
                  stripe
                  height="180"
                  style="width: 100%; background: transparent"
                  :header-cell-style="{
                    background: '#183272',
                    color: '#b8e8ff',
                    fontWeight: 'normal',
                    fontSize: '12px',
                    textAlign: 'center',
                    padding: '6px 0',
                  }"
                  :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                  @row-click="handleReweldRowClick"
                >
                  <el-table-column prop="bentID" label="后行钢卷号" width="120" />
                  <el-table-column prop="weldTimes" label="焊接次数" width="80" />
                  <el-table-column prop="createTime" label="焊接时间" width="180" />
                </el-table>
                <!-- 条件渲染：停机信息录入表格 -->
                <div
                  v-else-if="table.title === '停机信息录入'"
                  class="arpe-table-scroll-x"
                  @mousemove="handleTableMouseMove"
                  @mouseleave="handleTableMouseLeave"
                >
                  <el-table
                    :data="table.data"
                    stripe
                    height="180"
                    :header-cell-style="{
                      background: '#183272',
                      color: '#b8e8ff',
                      fontWeight: 'normal',
                      fontSize: '12px',
                      textAlign: 'center',
                      padding: '6px 0',
                    }"
                    :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                    @row-click="handleShutdownRowClick"
                  >
                    <el-table-column prop="hotCoilId" label="原料卷号" width="120" />
                    <el-table-column prop="duration" label="停机时长" width="90" />
                    <el-table-column prop="stopType" label="停机类型" width="100" />
                    <el-table-column prop="stopStartTime" label="停机开始时间" width="180" />
                    <el-table-column prop="stopEndTime" label="停机结束时间" width="180" />
                  </el-table>
                </div>
                <!-- 条件渲染：换辊统计表格 -->
                <el-table
                  v-else-if="table.title === '换辊统计'"
                  :data="table.data"
                  stripe
                  height="180"
                  style="width: 100%; background: transparent"
                  :header-cell-style="{
                    background: '#183272',
                    color: '#b8e8ff',
                    fontWeight: 'normal',
                    fontSize: '12px',
                    textAlign: 'center',
                    padding: '6px 0',
                  }"
                  :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                  @row-click="handleRollChangeRowClick"
                >
                  <el-table-column prop="rollerNO" label="辊号" />
                  <el-table-column prop="loadTime" label="换辊时间" />
                  <el-table-column prop="rollType" label="辊类型" />
                </el-table>
                <!-- 条件渲染：异常剪切状态表格 -->
                <el-table
                  v-else-if="table.title === '异常剪切状态'"
                  :data="table.data"
                  stripe
                  height="180"
                  style="width: 100%; background: transparent"
                  :header-cell-style="{
                    background: '#183272',
                    color: '#b8e8ff',
                    fontWeight: 'normal',
                    fontSize: '12px',
                    textAlign: 'center',
                    padding: '6px 0',
                  }"
                  :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                  @row-click="handleAbnormalCutRowClick"
                >
                  <el-table-column prop="entid" label="原料卷号" width="120" />
                  <el-table-column prop="headCutTimesAct" label="设定值" />
                  <el-table-column prop="headCutTimesMax" label="实际值" />
                </el-table>
                <el-table
                  v-else-if="table.title === '开卷机异常统计'"
                  :data="uncoilerAbnormalTableData"
                  stripe
                  height="180"
                  style="width: 100%; background: transparent"
                  :header-cell-style="{
                    background: '#183272',
                    color: '#b8e8ff',
                    fontWeight: 'normal',
                    fontSize: '12px',
                    textAlign: 'center',
                    padding: '6px 0',
                  }"
                  :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                >
                  <el-table-column prop="entID" label="卷号" width="120" />
                  <el-table-column prop="load" label="开卷机装卷(秒)" width="120" />
                  <el-table-column prop="expand" label="开卷(秒)" width="100" />
                  <el-table-column prop="straight" label="穿带(秒)" width="100" />
                  <el-table-column prop="cut" label="剪切(秒)" width="100" />
                </el-table>
                <el-table
                  v-else
                  :data="table.data"
                  stripe
                  height="180"
                  style="width: 100%; background: transparent"
                  :header-cell-style="{
                    background: '#183272',
                    color: '#b8e8ff',
                    fontWeight: 'normal',
                    fontSize: '12px',
                    textAlign: 'center',
                    padding: '6px 0',
                  }"
                  :cell-style="{ color: '#c0c4cc', fontSize: '12px', textAlign: 'center', padding: '6px 0', background: 'transparent' }"
                >
                  <el-table-column prop="coilNo" label="卷号" width="80" />
                  <el-table-column prop="time" label="时间" width="100" />
                  <el-table-column prop="entryEff" label="入口效率" width="80" />
                  <el-table-column prop="processEff" label="工艺效率" width="80" />
                  <el-table-column prop="reason" label="异常原因" width="100" />
                  <el-table-column prop="normalRate" label="正常率" width="80" />
                </el-table>
              </div>
            </div>
          </div>
        </div>
        <!-- 新增柱状图区域
        <div class="arpe-row arpe-row-bar">
          <div class="arpe-bar-chart-card">
             <div class="arpe-bar-chart-title">设备效率对比</div>
              <div ref="arpeBarChartRef" class="arpe-bar-chart"></div>
          </div>
        </div> -->
      </div>
      <!-- 右侧钢卷列 -->
      <div class="arpe-side-rolls arpe-side-rolls-right">
        <div v-for="(img, idx) in rightRolls" :key="'right-roll-' + idx" class="arpe-roll-img-wrap">
          <img :src="img" class="arpe-roll-img" />
        </div>
      </div>
    </div>
  </div>
  <!-- 辊位图弹窗 -->
  <el-dialog
    v-model="rollDetailsVisible"
    title="辊位图详情"
    width="90%"
    top="5vh"
    :close-on-press-escape="true"
    class="roll-details-dialog"
    modal-class="roll-details-mask"
    :style="{
      '--el-dialog-bg-color': 'rgba(10, 24, 48, 0.98)',
      '--el-bg-color': 'rgba(10, 24, 48, 0.98)',
      '--el-bg-color-overlay': 'rgba(10, 24, 48, 0.98)',
      background: 'rgba(10, 24, 48, 0.98) !important',
      border: '2px solid #00f6ff',
      borderRadius: '16px',
      boxShadow: '0 0 40px rgba(0, 246, 255, 0.4), inset 0 0 20px rgba(0, 246, 255, 0.1)',
      backdropFilter: 'blur(15px)',
    }"
  >
    <div
      style="
        width: 100%;
        height: 80vh;
        background: rgba(28, 58, 99, 0.7);
        border: 1px solid rgba(90, 130, 190, 0.4);
        border-radius: 8px;
        box-shadow: 0 0 10px rgba(11, 93, 209, 0.15);
        display: flex;
        align-content: center;
        justify-content: center;
        padding: 14px;
      "
    >
      <RollPosImage2280 r-group="5703/2280酸轧机组" svg-url="/rollPosImage/2280.svg" style="width: 100%; flex-grow: 1" />
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
  import { onMounted, onUnmounted, nextTick, ref, watch, computed, onBeforeUnmount } from 'vue';
  import * as echarts from 'echarts/core';
  import { GaugeChart, RadarChart, PieChart, BarChart } from 'echarts/charts';
  import { TooltipComponent, GraphicComponent, LegendComponent, TitleComponent, GridComponent } from 'echarts/components';
  import { CanvasRenderer } from 'echarts/renderers';
  import { ElTable, ElTableColumn } from 'element-plus';
  import { useUserStore } from '/@/store/modules/system/user';
  import { acidRollingApi } from '/@/api/acidRollingProductionEfficiency/index';
  import { refreshSVG, initialSVG, refreshGraphical } from '/@/common/refreshSVG';
  import { rollingSimulationApi } from '/@/api/RollingSimulation/index';
  import axios from 'axios';
  import request from '/@/plugins/request/globleRequest';
  import { furnaceTempDynamicCtrlApi } from '/@/api/furnaceTempDynamicCtrl/index';
  import { weldMachineState } from '/@/views/common/FulllineTrack/full.line.track.status';
  import { useRouter } from 'vue-router';
  import { showdownApi } from '/@/api/report/shutdown/index';
  import RollPosImage2280 from '/@/views/common/RollPosImage/2280RollPosImage.vue';
  import { outputAnalysisApi } from '/@/api/report/TCM2208MillUnit/index';
  import ProdBarLine from '/@/views/reportforms/components/prodBarLine.vue';
  import { rollingMillStatusHandel } from '/@/views/common/FulllineTrack/RollingMillVibration';

  const controller = new AbortController();

  // 统一管理定时器
  const timers = {
    main: null as NodeJS.Timeout | null,
    warning: null as NodeJS.Timeout | null,
    ai: null as NodeJS.Timeout | null,
    por: null as NodeJS.Timeout | null,
  };

  // API重试机制
  async function fetchDataWithRetry(apiCall: () => Promise<any>, maxRetries = 3, delay = 1000): Promise<any> {
    for (let i = 0; i < maxRetries; i++) {
      try {
        return await apiCall();
      } catch (error: any) {
        if (axios.isCancel(error)) {
          throw error; // 如果是取消请求，直接抛出
        }
        if (i === maxRetries - 1) {
          console.error(`API调用失败，已重试${maxRetries}次:`, error);
          throw error;
        }
        console.warn(`API调用失败，${delay * (i + 1)}ms后重试 (${i + 1}/${maxRetries}):`, error.message);
        await new Promise((resolve) => setTimeout(resolve, delay * (i + 1)));
      }
    }
  }

  echarts.use([
    TooltipComponent,
    GraphicComponent,
    GaugeChart,
    RadarChart,
    PieChart,
    LegendComponent,
    TitleComponent,
    CanvasRenderer,
    BarChart,
    GridComponent,
  ]);

  // 仪表盘与指示灯区图片
  import meter1 from '../../assets/images/szxl/切图 322.png';
  import meter2 from '../../assets/images/szxl/切图 322(2).png';
  import meter3 from '../../assets/images/szxl/切图 322(3).png';
  import meter4 from '../../assets/images/szxl/切图 322(1).png';
  import meter5 from '../../assets/images/szxl/切图 322(4).png';
  import meter6 from '../../assets/images/szxl/切图 322(5).png';

  const meters = [meter1, meter2, meter3, meter4, meter5, meter6];
  // 钢卷图片路径
  import img1 from '../../assets/images/szxl/切图 324.png';
  import img2 from '../../assets/images/szxl/切图 324(1).png';
  import img3 from '../../assets/images/szxl/切图 324(2).png';
  import img4 from '../../assets/images/szxl/切图 324(3).png';

  const rollImgs = [img1, img2, img3, img4];

  const data = ref([
    { menuName: 'acidRollingProductionEfficiencys', menuTitle: '酸轧生产效率主页', menuId: '1' },
    // { menuName: 'indexY', menuTitle: '主页 改' },
    { menuName: 'singleRollProductionEfficiencyAnalysis', menuTitle: '单卷生产效率分析评价' },
    { menuName: 'reWeldingFrequencyTraceability', menuTitle: '重焊次数追溯' },
    { menuName: 'shutdownStatistics', menuTitle: '停机明细及统计' },
    { menuName: 'productionschedulereport', menuTitle: '生产时序统计' },
    { menuName: 'productionspeed', menuTitle: '轧机速度未达成率' },
    { menuName: 'analysisdiagnosis', menuTitle: '生产效率分析诊断' },
    { menuName: 'rollchange', menuTitle: '换辊明细' },
  ]);

  // 生成更密集的钢卷列（如原图12-13个）
  function getDenseRolls(n = 13) {
    return Array.from({ length: n }, (_, i) => rollImgs[i % rollImgs.length]);
  }

  const leftRolls = getDenseRolls(13);
  const rightRolls = getDenseRolls(13);
  const technologicalName = 'TCM2280';

  // 辊位图弹窗相关
  const rollDetailsVisible = ref(false);
  const currentRollData = ref({
    rGroup: '5703/2280酸轧机组',
    svgUrl: '/rollPosImage/2280.svg',
  });
  //const rollPosImageRef = ref<InstanceType<typeof RollPosImage2280> | null>(null);
  const svgContainer = ref<HTMLElement | null>(null);

  // 监听 rollDetailsVisible 的变化
  watch(rollDetailsVisible, (newVal) => {
    console.log('rollDetailsVisible 变化:', newVal);
  });

  // 测试弹窗函数
  function testOpenDialog() {
    console.log('测试弹窗按钮被点击');
    openRollDetails({
      line: 'test',
      rGroup: 'test',
      area: 'test',
      pos: 'test',
      rType: 'test',
    });
  }

  function openRollDetails(rollData?: any) {
    console.log('openRollDetails 被调用，参数:', rollData);
    if (rollData) {
      // 如果传入了辊子数据，更新当前数据
      currentRollData.value = {
        rGroup: rollData.rGroup || '5703/2280酸轧机组',
        svgUrl: '/rollPosImage/2280.svg',
      };
      console.log('更新 currentRollData:', currentRollData.value);
    }
    rollDetailsVisible.value = true;
    console.log('设置 rollDetailsVisible 为 true');
  }

  // 绑定 SVG 辊子点击事件
  function bindSvgRollClickEvents() {
    if (!svgContainer.value) return;

    // 由于 svg-load 使用 SVG sprite，我们需要等待 SVG symbol 被加载
    // 使用轮询方式检查 SVG 内容是否已经渲染
    const checkSvgContent = () => {
      const svgElement = svgContainer.value?.querySelector('svg');
      if (svgElement) {
        // 检查是否有实际的 SVG 内容（不仅仅是空的 use 标签）
        const useElement = svgElement.querySelector('use');
        if (useElement) {
          // 检查 SVG symbol 是否已经被加载到页面中
          const symbolId = useElement.getAttribute('xlink:href') || useElement.getAttribute('href');
          if (symbolId) {
            const symbolElement = document.querySelector(symbolId);
            if (symbolElement) {
              console.log('SVG symbol 已加载:', symbolId);
              // 等待一小段时间确保 SVG symbol 被完全加载
              setTimeout(() => {
                bindClickEventsToSvg(svgElement);
              }, 200);
              return true;
            } else {
              console.log('SVG symbol 未找到:', symbolId);
            }
          }
        }
      }
      return false;
    };

    // 如果立即检查失败，则使用轮询
    if (!checkSvgContent()) {
      console.log('开始轮询检查 SVG 内容...');
      const interval = setInterval(() => {
        if (checkSvgContent()) {
          clearInterval(interval);
        }
      }, 100);

      // 设置最大等待时间，避免无限轮询
      setTimeout(() => {
        clearInterval(interval);
        console.log('SVG 加载超时，尝试直接绑定事件');
        // 即使超时也尝试绑定事件
        const svgElement = svgContainer.value?.querySelector('svg');
        if (svgElement) {
          bindClickEventsToSvg(svgElement);
        }
      }, 5000);
    }
  }

  // 为 SVG 元素绑定点击事件
  function bindClickEventsToSvg(svgElement: SVGElement) {
    console.log('开始绑定 SVG 点击事件');

    // 直接给整个 SVG 元素添加点击事件
    svgElement.style.cursor = 'pointer';
    svgElement.addEventListener('click', (event) => {
      event.stopPropagation();
      console.log('点击了 SVG 图');

      // 获取点击位置的信息
      const rect = svgElement.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;

      console.log('点击位置:', { x, y });
      console.log('准备调用 openRollDetails...');

      // 调用弹窗函数，传入默认参数
      openRollDetails({
        line: 'SVG点击',
        rGroup: '5703/2280酸轧机组',
        area: 'SVG区域',
        pos: `(${Math.round(x)}, ${Math.round(y)})`,
        rType: 'SVG点击',
      });

      console.log('openRollDetails 调用完成');
    });

    console.log('SVG 整体点击事件绑定完成');
  }
  const inletLooper = ref<number>(0);
  const middleLooper = ref<number>(0);
  const exportLooper = ref<number>(0);
  let tr: any = null;
  let por: any = null;
  let ti: any = null;
  const Intertemperature = ref<number>(0);
  const leftemperature = ref<number>(0);
  const righttemperature = ref<number>(0);
  // 新增：入口速度反馈小卡片数值（m/min）
  const entrySpeedFb = ref<number>(0);
  // 当前机组所有钢卷ID
  const coilIds = ref<any>({});

  const coilInfoDataLeft = ref<any>([{ entid: '' }]);
  const coilInfoDataMiddle = ref<any>([{ entid: '' }]);
  const coilInfoDataRight = ref<any>([{ entid: '' }]);

  // 仪表盘数据
  const gaugeData = [
    { id: 'gauge-entry', value: 0, label: '入口段速度' },
    { id: 'gauge-process', value: 0, label: '工艺段速度' },
    { id: 'gauge-skinpass', value: 0, label: '光整段速度' },
    { id: 'gauge-tcm', value: 0, label: 'TCM速度' },
    { id: 'gauge-welder', value: 0, label: '焊机速度' },
  ];

  let gaugeInstances: echarts.ECharts[] = [];
  let intervalId: any = null;

  const entranceMaterialRollcellStyle = ({ row, column, rowIndex, columnIndex }: { row: any; column: any; rowIndex: any; columnIndex: any }) => {
    let cellStyle;
    // 定义样式变量
    cellStyle = { color: coilIds.value.colors[row.INNER_IN_MAT_NO] };
    return cellStyle;
  };

  const getColors = (coilId: string) => {
    return { color: coilIds?.value.colors?.[coilId] };
  };

  function getGaugeOption(val: number) {
    return {
      series: [
        {
          type: 'gauge',
          center: ['50%', '50%'],
          radius: '80%',
          startAngle: 225,
          endAngle: -45,
          max: 300,
          axisLine: {
            roundCap: true,
            lineStyle: {
              width: 7,
              color: [
                [
                  1,
                  new echarts.graphic.LinearGradient(0, 1, 0.9, 1, [
                    { offset: 0, color: '#D64444' },
                    { offset: 0.2, color: '#D86E6D' },
                    { offset: 0.5, color: '#F1F3F4' },
                    { offset: 0.65, color: '#F1F3F4' },
                    { offset: 0.8, color: '#79ACF6' },
                    { offset: 1, color: '#1976FD' },
                  ]),
                ],
              ],
            },
          },
          pointer: {
            length: '90%',
            width: 2,
            color: '#FFFFFF',
          },
          axisTick: {
            distance: -14,
            length: 2,
            lineStyle: { color: '#4B83F7', width: 2 },
          },
          splitLine: {
            distance: -16,
            length: 6,
            lineStyle: { color: '#4B83F7', width: 2 },
          },
          axisLabel: {
            color: '#FFF',
            fontSize: 14,
            distance: -30,
            rotate: 'tangential',
            formatter: function (value: any) {
              return '';
            },
          },
          title: {
            offsetCenter: [0, '70%'],
            fontSize: 12,
            color: '#FFF',
          },
          detail: {
            fontSize: 18,
            offsetCenter: [0, '30%'],
            valueAnimation: true,
            formatter: function (value: any) {
              return Math.round(value);
            },
            color: '#FFF',
          },
          data: [
            {
              value: val,
              name: 'mpm',
            },
          ],
        },
      ],
    };
  }

  function initGauges() {
    gaugeData.forEach((item) => {
      const dom = document.getElementById(item.id);
      if (dom) {
        const chart = echarts.init(dom);
        chart.setOption(getGaugeOption(item.value));
        gaugeInstances.push(chart);
      }
    });
  }

  const setValue = ref(0);
  const actualValue = ref(0);

  async function fetchGaugeData() {
    try {
      const { data: res } = await fetchDataWithRetry(() =>
        axios.get('http://10.171.7.100:8090/restapi?name=TCM2280_itemtag', { signal: controller.signal })
      );
      const { data: res2 } = await fetchDataWithRetry(() =>
        axios.get('http://10.171.7.100:8090/restapi?name=TCM2280_zonetrk', { signal: controller.signal })
      );
      // 获取活套数据
      const { data: realData } = await fetchDataWithRetry(() =>
        axios.get('http://10.171.7.100:8090/restapi?name=TCM2280_RealData', { signal: controller.signal })
      );

      // 获取速度数据
      const entrySpeed = Number(res['M_010_011DS_ANS']) || 0;
      const processSpeed = Number(res['M_010_103NI']) || 0;
      const skinpassSpeed = Number(res['M_400_262NI']) || 0;
      const tcmSpeed = Number(res['M_010_014DS_ANS']) || 0;
      const welderSpeed = Number(res['M_010_105NI']) || 0;
      // 获取设定值和实测值
      setValue.value = Number(res['M_201_141NI']) || 0;
      actualValue.value = Number(res['M_201_142NI']) || 0;

      leftemperature.value = Number(parseFloat(res['M_211_239NI']).toFixed(0)) || 0;
      Intertemperature.value = Number(parseFloat(res['M_211_249NI']).toFixed(0)) || 0;
      righttemperature.value = Number(parseFloat(res['M_211_259NI']).toFixed(0)) || 0;

      // 获取活套套量数据
      // 新增：入口速度反馈（L_AGC_STRIPSFB0）取整显示到小卡片
      entrySpeedFb.value = Math.round(Number(res['L_AGC_STRIPSFB0']) || 0);
      const inletLooperValue = Number(realData['L_ELPR_PosFbk_1']) || 0;
      const middleLooperValue = Number(realData['L_ILPR_PosFbk_1']) || 0;
      const exportLooperValue = Number(realData['L_XLPR_PosFbk_1']) || 0;

      // 调试输出
      console.log('fetchGaugeData 活套套量:', inletLooperValue, middleLooperValue, exportLooperValue);
      // 赋值给百分比变量（如需归一化请自行调整）
      inletLooperPercent.value = inletLooperValue;
      middleLooperPercent.value = middleLooperValue;
      exportLooperPercent.value = exportLooperValue;

      // 更新仪表盘数据
      gaugeData[0].value = entrySpeed;
      gaugeData[1].value = processSpeed;
      gaugeData[2].value = skinpassSpeed;
      gaugeData[3].value = tcmSpeed;
      gaugeData[4].value = welderSpeed;

      // 更新仪表盘显示
      gaugeInstances.forEach((chart, idx) => {
        if (chart) {
          chart.setOption(getGaugeOption(gaugeData[idx].value));
        }
      });

      // 更新活套套量柱形图
      const bar1 = echarts.getInstanceByDom(document.getElementById('bar1') as HTMLElement);
      if (bar1) {
        bar1.setOption({
          xAxis: {
            data: ['3#', '2#', '1#'],
            axisLabel: {
              formatter: function (value: string) {
                return value;
              },
              color: '#b2eaff',
              fontSize: 14,
              textShadow: '0 0 6px #00f6ff',
              align: 'center',
              margin: 12,
            },
          },
          yAxis: {
            min: 0,
            max: 100,
          },
          series: [
            {
              data: [Math.round(exportLooperValue), Math.round(middleLooperValue), Math.round(inletLooperValue)],
              barWidth: 56, // 更宽
              label: {
                show: true,
                position: 'inside',
                color: '#fff',
                fontWeight: 'bold',
                fontSize: 18,
                formatter: function (params: any) {
                  return params.value + '%';
                },
              },
            },
          ],
        });
      }

      // --- 新增：开卷机/焊机时序跟踪渲染 ---
      const pie2 = echarts.getInstanceByDom(document.getElementById('pie2') as HTMLElement);
      const pie3 = echarts.getInstanceByDom(document.getElementById('pie3') as HTMLElement);
      const pie4 = echarts.getInstanceByDom(document.getElementById('pie4') as HTMLElement); // 新增

      let uncoilerPieData: PieDataItem[] = [];
      let welderPieData: PieDataItem[] = [];
      let gray = false;
      let uncoiler1PieData: PieDataItem[] = [];
      let uncoiler2PieData: PieDataItem[] = [];
      try {
        const res2 = await fetchDataWithRetry(() => rollingSimulationApi.rest({ name: 'TCM2280_zonetrk' }, { signal: controller.signal }));
        const por1CoilNo = res2?.data?.por1CoilNo;
        const por2CoilNo = res2?.data?.por2CoilNo;
        const por = res2?.data?.por;
        let currentCoilNo = '';
        if (por === '1') {
          currentCoilNo = por1CoilNo;
        } else if (por === '2') {
          currentCoilNo = por2CoilNo;
        }
        if (currentCoilNo) {
          const effRes = await acidRollingApi.getAcidEfficiency({ entid: currentCoilNo }, { signal: controller.signal });
          uncoilerPieData = convertUncoilerDataToPie(effRes?.data?.data || {});
          welderPieData = convertWelderDataToPie(effRes?.data?.data || {});
          gray = false;
        } else {
          uncoilerPieData = [];
          welderPieData = [];
          gray = true;
        }
        // 新增：1#开卷机数据
        if (por1CoilNo) {
          const effRes1 = await acidRollingApi.getAcidEfficiency({ entid: por1CoilNo }, { signal: controller.signal });
          uncoiler1PieData = convertUncoilerDataToPie(effRes1?.data?.data || {});
        } else {
          uncoiler1PieData = [];
        }
        // 新增：2#开卷机数据
        if (por2CoilNo) {
          const effRes2 = await acidRollingApi.getAcidEfficiency({ entid: por2CoilNo }, { signal: controller.signal });
          uncoiler2PieData = convertUncoilerDataToPie(effRes2?.data?.data || {});
        } else {
          uncoiler2PieData = [];
        }
        // 只渲染当前工作卷
        if (pie2) pie2.setOption(pieOptionFromPieData(welderPieData, gray));
        if (pie3) pie3.setOption(pieOptionFromPieData(uncoiler2PieData, false)); // 2#开卷机时序跟踪
        if (pie4) pie4.setOption(pieOptionFromPieData(uncoiler1PieData, false)); // 1#开卷机时序跟踪
      } catch (e: any) {
        if (axios.isCancel(e)) {
          console.log('Request canceled: getAcidEfficiency');
          return;
        }
        console.error('获取时序跟踪数据失败:', e);
        if (pie2) pie2.setOption(pieOptionFromPieData([], true));
        if (pie3) pie3.setOption(pieOptionFromPieData([], true));
        if (pie4) pie4.setOption(pieOptionFromPieData([], true)); // 新增异常兜底
      }
      // --- end ---

      // 新增：获取最大设定值，保留整数
      inletLooperMaxSet.value = Math.round(Number(realData['M_101_214DS_ANS']) || 0);
      middleLooperMaxSet.value = Math.round(Number(realData['M_300_110DS_ANS']) || 0);
      exportLooperMaxSet.value = Math.round(Number(realData['M_300_113DS_ANS']) || 0);

      // 左侧柱状图：按实时数据（功率/扭矩）构建，与示例组件一致
      try {
        const racks = [
          { name: '1#机架', data1: Number(parseFloat(res['M_400_512NI']).toFixed(2)), data2: Number(parseFloat(res['M_506_104NI']).toFixed(2)) },
          { name: '2#机架', data1: Number(parseFloat(res['M_400_514NI']).toFixed(2)), data2: Number(parseFloat(res['M_506_114NI']).toFixed(2)) },
          { name: '3#机架', data1: Number(parseFloat(res['M_400_516NI']).toFixed(2)), data2: Number(parseFloat(res['M_506_124NI']).toFixed(2)) },
          { name: '4#机架', data1: Number(parseFloat(res['M_400_518NI']).toFixed(2)), data2: Number(parseFloat(res['M_506_134NI']).toFixed(2)) },
          { name: '5#机架', data1: Number(parseFloat(res['M_400_520NI']).toFixed(2)), data2: Number(parseFloat(res['M_506_144NI']).toFixed(2)) },
        ].reverse();
        productionEfficiencyHours.value = racks.map((it) => it.name);
        predictedProduction.value = racks.map((it) => it.data1);
        actualProduction.value = racks.map((it) => it.data2);
        updateProductionEfficiencyChart();
      } catch (e) {
        // 忽略实时数据缺失导致的异常
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: fetchGaugeData');
        return;
      }
      console.error('获取仪表盘数据失败:', e);
    }
  }

  function disposeGauges() {
    gaugeInstances.forEach((chart) => chart.dispose());
    gaugeInstances = [];
  }

  function resizeGauges() {
    gaugeInstances.forEach((chart) => chart.resize());
  }

  // 底部右侧柱形图（现在使用prodBarLine组件）
  const millUnitX = ref<string[]>([]);
  const millUnitTarget = ref<number[]>([]);
  const millUnitActual = ref<number[]>([]);
  const millUnitAchiRate = ref<number[]>([]);
  const millUnitDateType = ref<string>('day');
  // 生产卷数（与 prodBarLine.vue 一致）
  const millUnitTargetRollCounts = ref<number[]>([]);
  const millUnitActualRollCounts = ref<number[]>([]);
  // 新增：两个柱形图的数值（0-100 表示高度百分比）。可替换为真实数据。
  const dayPlanIssued = ref<number>(68); // 日计划下达产量（柱状图高度百分比）
  const dayPlanIssuedValue = ref<number>(0); // 日计划下达产量（实际数值，用于显示）
  const dayPlanAchi = ref<number>(92); // 日计划产量累计达成率（%）
  const DAY_PLAN_FIXED_VALUE = 6765; // 日计划产量累计达成率计算的固定分母

  // 新增：六个统计卡片数据（左侧）
  const statsCards = ref<Array<{ label: string; value: string | number; suffix?: string }>>([
    { label: '日产量', value: 4482, suffix: '吨' },
    { label: '日产记录', value: 10455, suffix: '吨' },
    { label: '月产量', value: 102146, suffix: '吨' },
    { label: '月产记录', value: 214901, suffix: '吨' },
    { label: '月设定产量', value: 198700, suffix: '吨' },
    { label: '月完成率', value: 55, suffix: '%' },
  ]);

  async function fetchMillUnitBarData() {
    const param = { dateType: millUnitDateType.value } as any;
    try {
      const res = await outputAnalysisApi.getTCMMillUnitData(param);
      console.log('机组产量数据接口返回:', res);
      const list = Array.isArray(res?.data?.data) ? res.data.data : [];
      console.log('解析后的列表数据:', list);

      const x: string[] = [];
      const target: number[] = [];
      const actual: number[] = [];
      const rate: number[] = [];
      const targetCounts: number[] = [];
      const actualCounts: number[] = [];

      // 获取今天的日期（格式：YYYY-MM-DD 或根据实际接口返回的日期格式）
      const today = new Date();
      const todayStr = today.toISOString().split('T')[0]; // YYYY-MM-DD
      const todayStr2 = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`; // YYYY-MM-DD
      console.log('今天的日期:', todayStr, todayStr2);

      let todayData = null; // 存储今天的数据

      for (const e of list) {
        const dateStr = String(e.prodDate ?? e.category ?? '');
        x.push(dateStr);
        target.push(parseFloat((e.target ?? 0).toFixed ? (e.target as number).toFixed(2) : Number(e.target || 0).toFixed(2)));
        actual.push(parseFloat((e.actual ?? 0).toFixed ? (e.actual as number).toFixed(2) : Number(e.actual || 0).toFixed(2)));
        rate.push(parseFloat(((e.achi ?? 0) * 100).toFixed(2)));
        targetCounts.push(Number(e.targetRoll ?? 0));
        actualCounts.push(Number(e.actualRoll ?? 0));

        // 查找今天的数据
        if (dateStr === todayStr || dateStr === todayStr2 || dateStr.includes(todayStr) || dateStr.includes(todayStr2)) {
          todayData = e;
        }
      }

      // 如果找到今天的数据，使用今天的；否则使用最后一条数据（最新数据）
      const latestData = todayData || (list.length > 0 ? list[list.length - 1] : null);

      // 注意：日计划数据现在由 fetchDayPlanData() 独立获取，这里不再处理
      if (!latestData) {
        console.warn('⚠️ 未找到有效数据，使用初始值。list.length =', list.length);
      }
      millUnitX.value = x;
      millUnitTarget.value = target;
      millUnitActual.value = actual;
      millUnitAchiRate.value = rate;
      millUnitTargetRollCounts.value = targetCounts;
      millUnitActualRollCounts.value = actualCounts;
      // 不再需要initHourlyBar()，因为使用prodBarLine组件
    } catch (err) {
      millUnitX.value = [];
      millUnitTarget.value = [];
      millUnitActual.value = [];
      millUnitAchiRate.value = [];
      millUnitTargetRollCounts.value = [];
      millUnitActualRollCounts.value = [];
      // 不再需要initHourlyBar()，因为使用prodBarLine组件
    }
  }

  // 新增：独立获取日计划数据（固定使用天为单位，不受millUnitDateType影响）
  async function fetchDayPlanData() {
    const param = { dateType: 'day' }; // 固定使用天
    try {
      const res = await outputAnalysisApi.getTCMMillUnitData(param);
      console.log('日计划数据接口返回:', res);
      const list = Array.isArray(res?.data?.data) ? res.data.data : [];

      // 获取今天的日期
      const today = new Date();
      const todayStr = today.toISOString().split('T')[0]; // YYYY-MM-DD
      const todayStr2 = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;

      let todayData = null;

      // 查找今天的数据
      for (const e of list) {
        const dateStr = String(e.prodDate ?? e.category ?? '');
        if (dateStr === todayStr || dateStr === todayStr2 || dateStr.includes(todayStr) || dateStr.includes(todayStr2)) {
          todayData = e;
          break;
        }
      }

      // 如果找到今天的数据，使用今天的；否则使用最后一条数据（最新数据）
      const latestData = todayData || (list.length > 0 ? list[list.length - 1] : null);

      if (latestData) {
        // 日计划下达产量：使用预测产量（target）
        const targetValue = Number(latestData.target ?? 0);
        dayPlanIssuedValue.value = targetValue; // 保存实际数值用于显示

        // 计算柱状图高度百分比（使用所有天的最大值作为基准）
        const allTargets = list.map((e: any) => Number(e.target ?? 0)).filter((v: number) => !isNaN(v) && v > 0);
        const maxTarget = allTargets.length > 0 ? Math.max(...allTargets) : 100;
        dayPlanIssued.value = Math.min(100, Math.max(0, (targetValue / maxTarget) * 100));

        // 日计划产量累计达成率：日计划下达产量 ÷ 6765 × 100
        const achiValue = (targetValue / DAY_PLAN_FIXED_VALUE) * 100;
        dayPlanAchi.value = Math.max(0, achiValue); // 只限制最小值为0，允许超过100%

        console.log('✅ 日计划数据更新（固定天）:', {
          date: latestData.prodDate ?? latestData.category,
          targetValue,
          dayPlanIssuedValue: dayPlanIssuedValue.value,
          maxTarget,
          dayPlanIssued: dayPlanIssued.value,
          achiValue,
          dayPlanAchi: dayPlanAchi.value,
          formula: `${targetValue} / ${DAY_PLAN_FIXED_VALUE} * 100 = ${achiValue.toFixed(2)}%`,
          note: dayPlanAchi.value > 100 ? '✓ 超过100%达成' : '',
        });
      } else {
        console.warn('⚠️ 日计划数据未找到有效数据');
      }
    } catch (err) {
      console.error('❌ 获取日计划数据失败:', err);
    }
  }

  // 删除了initHourlyBar函数，因为现在使用prodBarLine组件

  onBeforeMount(() => {
    useUserStore().setTagNav(data.value);
  });

  onMounted(() => {
    nextTick(() => {
      // 初始化仪表盘
      initGauges();

      // 获取数据并更新
      fetchGaugeData();
      getDayAMonthOut(); // 新增：获取日产量月产量数据
      getHourCount(); // 新增：获取小时产量数据
      fetchDayPlanData(); // 新增：获取日计划数据（固定使用天）
      fetchTcmOutputRecord(); // 新增：获取日产量和日产记录数据（新接口）

      // 延迟调用轧机颜色更新，确保SVG已经加载完成
      setTimeout(() => {
        getRollingMillVibration();
      }, 1000);

      // 定时刷新数据（使用统一管理）
      timers.main = setInterval(() => {
        getZoneTrk();
        getSteelInfo();
        fetchGaugeData();
        fetchDiscShearPieData(); // 新增：圆盘剪时序跟踪定时刷新
        fetchShutdownTableData(); // 新增：定时获取停机信息数据
        fetchRollChangeTableData(); // 新增：定时获取换辊统计数据
        getDayAMonthOut(); // 新增：日产量/记录、月产量/记录、月设定、月完成率 定时刷新
        getHourCount(); // 新增：小时产量定时刷新
        fetchDayPlanData(); // 新增：日计划数据定时刷新（固定使用天）
        fetchTcmOutputRecord(); // 新增：日产量和日产记录数据定时刷新（新接口）
        getRollingMillVibration(); // 新增：定时更新轧机颜色
      }, 5000);

      // 监听窗口大小变化
      window.addEventListener('resize', resizeGauges);

      // 绑定SVG辊子点击事件
      bindSvgRollClickEvents();

      // 初始化底部右侧柱形图（拉取酸轧机组产量数据）
      fetchMillUnitBarData();
    });
    testFurnaceApi(); // 新增：页面挂载时测试接口
    fetchReWeldTableData(); // 新增：获取重焊统计数据
    fetchShutdownTableData(); // 新增：获取停机信息数据
    fetchRollChangeTableData(); // 新增：获取换辊统计数据
    timers.warning = setInterval(async () => {
      try {
        const res = await fetchDataWithRetry(() => acidRollingApi.getEarlyWarning({}, { signal: controller.signal }));
        if (res && res.data && Array.isArray(res.data.data)) {
          earlyWarningList.value = res.data.data;
        } else {
          earlyWarningList.value = [];
        }
      } catch (e: any) {
        if (axios.isCancel(e)) {
          console.log('Request canceled: getEarlyWarning');
          return;
        }
        console.error('获取预警数据失败:', e);
        earlyWarningList.value = [];
      }
    }, 5000);
  });

  const getSteelInfo = async () => {
    // let param = {
    //   coilIds: coilIds.value.coilIds,
    // };
    await rollingSimulationApi
      .getSteelInfo(coilIds.value.coilIds, { signal: controller.signal })
      .then((res) => {
        // 添加空值检查，防止 forEach 报错
        if (res?.data?.data && Array.isArray(res.data.data)) {
          res.data.data.forEach((item: any) => {
            if (item.entid === coilInfoDataLeft.value[0].entid) {
              coilInfoDataLeft.value[0] = item;
            }
            if (item.entid === coilInfoDataMiddle.value[0].entid) {
              coilInfoDataMiddle.value[0] = item;
            }
            if (item.entid === coilInfoDataRight.value[0].entid) {
              coilInfoDataRight.value[0] = item;
            }
          });
        }
      })
      .catch((err) => {
        if (axios.isCancel(err)) {
          console.log('getSteelInfo canceled');
        } else {
          // Handle other errors if needed
          console.error('getSteelInfo error', err);
        }
      });
  };

  // 获取轧机震动数据并更新轧机颜色（完全参照参考文件实现）
  const getRollingMillVibration = async () => {
    try {
      let res = await request.get('/mq/rollingMillVibration');
      if (res) {
        rollingMillStatusHandel(res);
      }
    } catch (err) {
      // 静默失败，不输出错误，避免影响其他功能
    }
  };

  // 钢卷跟踪
  async function getZoneTrk() {
    let param = {
      name: 'TCM2280_zonetrk',
    };
    rollingSimulationApi.rest(param).then((res) => {
      let zones = res.data.zoneno;
      // .coilIds.filter((item: any) => !item.endsWith('book'));
      coilIds.value = SearchForCoidId(zones);
      coilIds.value.coilIds = coilIds.value.coilIds.filter((item: any) => item != 'ENTIDBOOK');
      coilInfoDataLeft.value[0].entid = coilIds.value.coilIds[2] ?? '';
      coilInfoDataMiddle.value[0].entid = coilIds.value.coilIds[1] ?? '';
      coilInfoDataRight.value[0].entid = coilIds.value.coilIds[0] ?? '';
      // console.log(zones[82]);
      weldMachineState(`${technologicalName}-welder`, res.data.weld);
      inletLooper.value = res.data['loop'][0];
      middleLooper.value = res.data['loop'][1];
      exportLooper.value = res.data['loop'][2];
      let trKey = `${technologicalName}-ZONE_tr${res.data.tr}`;
      let trpathKey = trKey + '_path';
      let porKey = `${technologicalName}-ZONE_por${res.data.por}`;
      let porpathKey = porKey + '_path';
      var arr = Object.keys(zones);
      /**开卷机和卷取机 */
      if (tr === null || tr !== res.data.tr) {
        tr = res.data.tr;
        refreshSVG(zones[arr.length - 1].ti % 10, trpathKey);
        refreshGraphical(zones[arr.length - 1].ti % 10, trKey);
        initialSVG(technologicalName, 'tr', res.data.tr);
      }
      if (por === null || por !== res.data.por) {
        por = res.data.por;
        if (res.data.por === 0) {
          initialSVG(technologicalName, 'por', '1');
          initialSVG(technologicalName, 'por', '2');
        }
      }
      if (ti === null || ti !== zones[0].ti) {
        ti = zones[0].ti;
        refreshSVG(zones[0].ti % 10, porpathKey);
        refreshGraphical(zones[0].ti % 10, porKey);
        initialSVG(technologicalName, 'por', res.data.por);
      }
      for (let i in zones) {
        let pathkey = `${technologicalName}-ZONE${i}`;
        console.log(pathkey);
        refreshSVG(zones[i].ti % 10, pathkey);
      }
      // 新增：同步生成进度条区段
      const zonesArr = Object.values(zones);
      // 每个区段都生成一个segment，与SVG同步，顺序反向
      progressSegments.value = [...zonesArr].reverse().map((zone: any) => ({
        percent: 1, // 每段等分，flex布局自动紧凑
        color: (ColourStrategy as any)[zone.ti % 10]('rgba', 0.38),
        coilId: zone.entId,
        label: zone.label || zone.entId || '',
      }));
    });
  }

  enum ColourType {
    ZERO = 0,
    ONE = 1,
    TWO = 2,
    THREE = 3,
    FOUR = 4,
    FIVE = 5,
    SEX = 6,
    SEVEN = 7,
    EIGHT = 8,
    NINE = 9,
    INITLINE = -1,
    INITLGRAPHICAL = -2,
  }

  const ColourStrategy = {
    [ColourType.ZERO]: () => '#FF6600',
    [ColourType.ONE]: () => '#FF00FF',
    [ColourType.TWO]: () => '#CC3300',
    [ColourType.THREE]: () => '#0099FF',
    [ColourType.FOUR]: () => '#F08080',
    [ColourType.FIVE]: () => '#C0C0C0',
    [ColourType.SEX]: () => 'rgba(255,128,64,255)',
    [ColourType.SEVEN]: () => '#C71585',
    [ColourType.EIGHT]: () => 'rgba(147,147,0,255)',
    [ColourType.NINE]: () => 'rgba(255,128,192,255)',
    [ColourType.INITLINE]: () => '#5F6368',
    [ColourType.INITLGRAPHICAL]: () => '#1E1E1E',
  };

  function SearchForCoidId(zones: any) {
    const keys = Object.keys(zones);
    const Arr = [];
    const color = [];
    for (let index = 0; index < keys.length; index++) {
      const element: any = keys[index];
      Arr.push(zones[element].entId);
      color.push((ColourStrategy as any)[zones[index].ti % 10]());
    }
    const newArr = Array.from(new Set(Arr));
    const colorArr = Array.from(new Set(color));
    const object: any = {};
    for (let index = 0; index < newArr.length; index++) {
      const element = newArr[index];
      object[element] = colorArr[index];
    }
    return {
      coilIds: Array.from(new Set(Arr)),
      colors: object,
    };
  }

  onUnmounted(() => {
    // 清理定时器
    if (intervalId) {
      clearInterval(intervalId);
    }

    // 销毁图表实例
    disposeGauges();
    // 不再需要hourlyBarInstance，因为使用prodBarLine组件

    // 移除事件监听
    window.removeEventListener('resize', resizeGauges);
    if (earlyWarningInterval) clearInterval(earlyWarningInterval);
    controller.abort();
  });

  let chartInstances: echarts.ECharts[] = [];

  function initCharts() {
    // 销毁旧实例，防止重复渲染
    chartInstances.forEach((c) => c.dispose());
    chartInstances = [];

    // 圆盘剪时序跟踪环形图 pie1
    const pie1Dom = document.getElementById('pie1');
    let pie1Inst: echarts.ECharts | null = null;
    if (pie1Dom) {
      pie1Inst = echarts.init(pie1Dom);
      pie1Inst.setOption(pieOptionFromPieData(discShearPieData.value));
      chartInstances.push(pie1Inst);
    }

    // 雷达图数据
    const radarOption = {
      tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(0,24,48,0.8)',
        borderColor: '#00f6ff',
        borderWidth: 1,
        textStyle: { color: '#fff' },
        formatter: '{b}: {c}',
      },
      radar: {
        indicator: [
          { name: '指标1', max: 100 },
          { name: '指标2', max: 100 },
          { name: '指标3', max: 100 },
          { name: '指标4', max: 100 },
          { name: '指标5', max: 100 },
        ],
        splitArea: {
          areaStyle: {
            color: ['rgba(0,246,255,0.05)', 'rgba(0,246,255,0.1)'],
            shadowColor: 'rgba(0,246,255,0.2)',
            shadowBlur: 10,
          },
        },
        axisLine: {
          lineStyle: {
            color: 'rgba(0,246,255,0.3)',
            shadowColor: '#00f6ff',
            shadowBlur: 10,
          },
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(0,246,255,0.3)',
            shadowColor: '#00f6ff',
            shadowBlur: 5,
          },
        },
        name: {
          color: '#b2eaff',
          fontSize: 13,
          textShadow: '0 0 8px #00f6ff',
        },
      },
      series: [
        {
          type: 'radar',
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: {
            shadowColor: '#00f6ff',
            shadowBlur: 10,
          },
          lineStyle: {
            width: 2,
            shadowColor: '#00f6ff',
            shadowBlur: 10,
          },
          areaStyle: {
            opacity: 0.4,
            shadowColor: '#00f6ff',
            shadowBlur: 20,
          },
          data: [
            {
              value: [80, 90, 70, 85, 60],
              name: 'Data 1',
              areaStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: 'rgba(0,246,255,0.6)' },
                  { offset: 1, color: 'rgba(0,246,255,0.1)' },
                ]),
              },
              lineStyle: { color: '#00f6ff' },
            },
            {
              value: [60, 70, 80, 60, 90],
              name: 'Data 2',
              areaStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: 'rgba(78,207,255,0.6)' },
                  { offset: 1, color: 'rgba(78,207,255,0.1)' },
                ]),
              },
              lineStyle: { color: '#4ecfff' },
            },
          ],
          animation: true,
          animationDuration: 2000,
          animationEasing: 'cubicInOut',
        },
      ],
    };

    // 柱状图数据
    const barOption = {
      backgroundColor: 'rgba(0,0,0,0)',
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(0,24,48,0.8)',
        borderColor: '#00f6ff',
        borderWidth: 1,
        textStyle: { color: '#fff' },
        axisPointer: {
          type: 'shadow',
          shadowStyle: {
            color: 'rgba(0,246,255,0.1)',
          },
        },
        formatter: function (params: any) {
          return `${params[0].name}<br/>套量：${params[0].value}%`;
        },
      },
      grid: {
        left: 10,
        right: 10,
        top: 20,
        bottom: 10,
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        data: ['1#', '2#', '3#'],
        axisLine: {
          lineStyle: {
            color: 'rgba(78,207,255,0.5)',
            shadowColor: '#00f6ff',
            shadowBlur: 10,
          },
        },
        axisLabel: {
          color: '#b2eaff',
          fontSize: 14,
          textShadow: '0 0 6px #00f6ff',
          interval: 0,
        },
      },
      yAxis: {
        type: 'value',
        name: '套量(%)',
        nameTextStyle: {
          color: '#b2eaff',
          fontSize: 14,
          padding: [0, 0, 0, 0],
          align: 'center',
        },
        nameLocation: 'middle',
        nameGap: 38,
        axisLine: {
          lineStyle: {
            color: 'rgba(78,207,255,0.5)',
            shadowColor: '#00f6ff',
            shadowBlur: 10,
          },
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(78,207,255,0.1)',
            type: 'dashed',
            shadowColor: '#00f6ff',
            shadowBlur: 5,
          },
        },
        axisLabel: {
          color: '#b2eaff',
          fontSize: 14,
          textShadow: '0 0 6px #00f6ff',
        },
      },
      series: [
        {
          name: '活套套量',
          type: 'bar',
          data: [0, 0, 0], // 初始数据，后续通过接口更新
          barWidth: 28, // 柱子加粗
          label: {
            show: true,
            position: 'inside',
            color: '#fff',
            fontWeight: 'bold',
            fontSize: 16,
            formatter: function (params: any) {
              return params.value + '%';
            },
          },
          itemStyle: {
            borderRadius: [8, 8, 0, 0],
            color: function (params: any) {
              const v = params.value;
              if (v < 20 || v > 90) {
                return '#ff4d4f'; // 红色
              }
              return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#00f6ff' },
                { offset: 1, color: 'rgba(0,246,255,0.3)' },
              ]);
            },
            shadowColor: '#00f6ff',
            shadowBlur: 20,
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 30,
              shadowColor: '#00f6ff',
            },
          },
          animation: true,
          animationDuration: 2000,
          animationEasing: 'cubicInOut',
        },
      ],
      legend: {
        show: true,
        data: ['set1#:%', 'set2#:%', 'set3#:%'],
        textStyle: {
          color: '#b2eaff',
          fontSize: 13,
        },
        bottom: 0,
        itemWidth: 18,
        itemHeight: 12,
        icon: 'rect',
      },
    };

    // 1#、2#开卷机时序跟踪数据
    const processNames = ['过程一', '过程二', '过程三', '过程四', '过程五', '过程六', '过程七'];
    let timePoints = [
      '2025-05-24 04:41:21',
      '2025-05-24 04:42:21',
      null,
      '2025-05-24 04:44:21',
      '2025-05-24 04:45:21',
      '2025-05-24 04:46:21',
      '2025-05-24 04:47:21',
      '2025-05-24 04:48:21',
    ];
    const standards = [83, 39, 93, 8, 76, 5, 74];

    // pieOption 支持传参
    function pieOption(timePoints: (string | null)[], processNames: string[], standards: number[]) {
      const timeDiffs = [];
      for (let i = 0; i < processNames.length; i++) {
        let diff = null;
        if (timePoints[i] && timePoints[i + 1]) {
          const t1 = new Date(timePoints[i] as string).getTime();
          const t2 = new Date(timePoints[i + 1] as string).getTime();
          diff = Math.abs(Math.floor((t2 - t1) / 1000));
        }
        timeDiffs.push({
          name: processNames[i],
          value: 1, // 强制每段一样大，实现7等分
          realValue: diff, // 真实时间差，null为无数据
          standard: standards[i],
        });
      }
      return {
        tooltip: {
          trigger: 'item',
          backgroundColor: 'rgba(0,24,48,0.8)',
          borderColor: '#00f6ff',
          borderWidth: 1,
          textStyle: { color: '#fff' },
          formatter: function (params: any) {
            const data = params.data;
            if (data.realValue === null) {
              return `${data.name}<br/>无数据`;
            }
            const isOver = data.realValue > data.standard;
            return `${data.name}<br/>实际时间：${data.realValue}秒<br/>标准时间：${data.standard}秒<br/>${
              isOver ? '<span style="color:#ff4d4f">超出标准</span>' : '<span style="color:#52c41a">正常</span>'
            }`;
          },
        },
        series: [
          {
            type: 'pie',
            radius: ['60%', '80%'],
            center: ['50%', '50%'],
            label: {
              show: true,
              color: '#fff',
            },
            data: timeDiffs.map((item) => ({
              value: 1,
              name: item.name,
              realValue: item.realValue,
              standard: item.standard,
              itemStyle: {
                color:
                  item.realValue === null
                    ? '#888' // 灰色
                    : item.realValue > item.standard
                    ? new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: '#ff4d4f' },
                        { offset: 1, color: 'rgba(255,77,79,0.3)' },
                      ])
                    : new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: '#52c41a' },
                        { offset: 1, color: 'rgba(82,196,26,0.3)' },
                      ]),
              },
            })),
          },
        ],
      };
    }

    // 其他环形图（如pie1、pie2）用原来的2段数据
    const pie12Option = {
      tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(0,24,48,0.8)',
        borderColor: '#00f6ff',
        borderWidth: 1,
        textStyle: { color: '#fff' },
        formatter: '{b}: {c}',
      },
      series: [
        {
          type: 'pie',
          radius: ['60%', '80%'],
          center: ['50%', '50%'],
          label: {
            show: true,
            position: 'outside',
            formatter: '{b}\n{c}',
            color: '#fff',
            fontSize: 12,
          },
          data: [
            { value: 60, name: 'Data 1' },
            { value: 40, name: 'Data 2' },
          ],
        },
      ],
    };

    // 初始化图表
    const radar1 = echarts.init(document.getElementById('radar1')!);
    radar1.setOption(radarOption);
    chartInstances.push(radar1);
    const radar2 = echarts.init(document.getElementById('radar2')!);
    radar2.setOption(radarOption);
    chartInstances.push(radar2);
    const bar1 = echarts.init(document.getElementById('bar1')!);
    bar1.setOption(barOption);
    chartInstances.push(bar1);
    const radar3 = echarts.init(document.getElementById('radar3')!);
    radar3.setOption(radarOption);
    chartInstances.push(radar3);
    const pie1 = echarts.init(document.getElementById('pie1')!);
    pie1.setOption(pie12Option);
    chartInstances.push(pie1);
    const pie2 = echarts.init(document.getElementById('pie2')!);
    pie2.setOption(pieOptionFromPieData([]));
    chartInstances.push(pie2);
    const pie3 = echarts.init(document.getElementById('pie3')!);
    pie3.setOption(pieOptionFromPieData([]));
    chartInstances.push(pie3);
    const pie4 = echarts.init(document.getElementById('pie4')!);
    pie4.setOption(pieOptionFromPieData([]));
    chartInstances.push(pie4);
  }
  function disposeCharts() {
    chartInstances.forEach((c) => c.dispose());
    chartInstances = [];
  }
  onMounted(() => {
    nextTick(() => {
      initCharts();
    });
    window.addEventListener('resize', () => {
      chartInstances.forEach((c) => c.resize());
      // 不再需要hourlyBarInstance.resize()，因为使用prodBarLine组件
    });

    // 获取时间差标准值（合并重复调用）
    fetchDataWithRetry(async () => {
      const res = await acidRollingApi.getDiffTime({}, { signal: controller.signal });
      console.log('getDiffTime 返回：', res);

      if (res && res.data && res.data.data && Array.isArray(res.data.data) && res.data.data.length > 0) {
        diffTimeStandard.value = res.data.data[0];
      }
      return res;
    }).catch((err) => {
      if (axios.isCancel(err)) {
        console.log('getDiffTime canceled');
      } else {
        console.error('getDiffTime 调用失败:', err);
      }
    });
  });
  // 统一清理所有定时器和资源
  function cleanupAllResources() {
    // 清理所有定时器
    Object.values(timers).forEach((timer) => {
      if (timer) {
        clearInterval(timer);
      }
    });

    // 清理图表实例
    disposeCharts();

    // 清理事件监听器
    window.removeEventListener('resize', () => chartInstances.forEach((c) => c.resize()));

    // 取消所有网络请求
    controller.abort();
  }

  onUnmounted(() => {
    cleanupAllResources();
  });

  // 6个表格的mock数据
  const tableList = [
    {
      title: '异常设备状态',
      data: [
        { coilNo: 'COC1', time: '10:30:00', entryEff: '93%', processEff: '95%', reason: '异常1', normalRate: '95%' },
        { coilNo: 'COC2', time: '10:35:00', entryEff: '92%', processEff: '94%', reason: '异常2', normalRate: '94%' },
        { coilNo: 'COC3', time: '10:40:00', entryEff: '91%', processEff: '93%', reason: '异常3', normalRate: '93%' },
        { coilNo: 'COC4', time: '10:45:00', entryEff: '90%', processEff: '92%', reason: '异常4', normalRate: '92%' },
      ],
    },
    {
      title: '停机信息录入',
      get data() {
        return shutdownTableData.value;
      },
    },
    {
      title: '换辊统计',
      get data() {
        return rollChangeTableData.value;
      },
    },
    {
      title: '重焊统计',
      data: [
        { coilNo: 'COC1', time: '10:30:00', entryEff: '93%', processEff: '95%', reason: '重焊A', normalRate: '95%' },
        { coilNo: 'COC2', time: '10:35:00', entryEff: '92%', processEff: '94%', reason: '重焊B', normalRate: '94%' },
        { coilNo: 'COC3', time: '10:40:00', entryEff: '91%', processEff: '93%', reason: '重焊C', normalRate: '93%' },
        { coilNo: 'COC4', time: '10:45:00', entryEff: '90%', processEff: '92%', reason: '重焊D', normalRate: '92%' },
      ],
    },
    {
      title: '异常剪切状态',
      get data() {
        return abnormalCutTableData.value;
      },
    },
    {
      title: '开卷机异常统计',
      data: [
        { coilNo: 'COC1', time: '10:30:00', entryEff: '93%', processEff: '95%', reason: '开卷异常A', normalRate: '95%' },
        { coilNo: 'COC2', time: '10:35:00', entryEff: '92%', processEff: '94%', reason: '开卷异常B', normalRate: '94%' },
        { coilNo: 'COC3', time: '10:40:00', entryEff: '91%', processEff: '93%', reason: '开卷异常C', normalRate: '93%' },
        { coilNo: 'COC4', time: '10:45:00', entryEff: '90%', processEff: '92%', reason: '开卷异常D', normalRate: '92%' },
      ],
    },
  ];

  // 新的表格数据
  const tableData = ref([
    {
      coilNo: 'COC202412001',
      time: '2024-12-01 10:30:00',
      entryEff: '93%',
      processEff: '95%',
      exportEff: '94%',
      totalEff: '94%',
      status: '正常',
      reason: '-',
      normalRate: '95%',
    },
    {
      coilNo: 'COC202412002',
      time: '2024-12-01 10:35:00',
      entryEff: '92%',
      processEff: '94%',
      exportEff: '93%',
      totalEff: '93%',
      status: '异常',
      reason: '设备故障',
      normalRate: '94%',
    },
    {
      coilNo: 'COC202412003',
      time: '2024-12-01 10:40:00',
      entryEff: '91%',
      processEff: '93%',
      exportEff: '92%',
      totalEff: '92%',
      status: '正常',
      reason: '-',
      normalRate: '93%',
    },
    {
      coilNo: 'COC202412004',
      time: '2024-12-01 10:45:00',
      entryEff: '90%',
      processEff: '92%',
      exportEff: '91%',
      totalEff: '91%',
      status: '警告',
      reason: '效率偏低',
      normalRate: '92%',
    },
    {
      coilNo: 'COC202412005',
      time: '2024-12-01 10:50:00',
      entryEff: '89%',
      processEff: '91%',
      exportEff: '90%',
      totalEff: '90%',
      status: '正常',
      reason: '-',
      normalRate: '91%',
    },
    {
      coilNo: 'COC202412006',
      time: '2024-12-01 10:55:00',
      entryEff: '88%',
      processEff: '90%',
      exportEff: '89%',
      totalEff: '89%',
      status: '异常',
      reason: '停机检修',
      normalRate: '90%',
    },
    {
      coilNo: 'COC202412007',
      time: '2024-12-01 11:00:00',
      entryEff: '87%',
      processEff: '89%',
      exportEff: '88%',
      totalEff: '88%',
      status: '正常',
      reason: '-',
      normalRate: '89%',
    },
    {
      coilNo: 'COC202412008',
      time: '2024-12-01 11:05:00',
      entryEff: '86%',
      processEff: '88%',
      exportEff: '87%',
      totalEff: '87%',
      status: '警告',
      reason: '换辊影响',
      normalRate: '88%',
    },
  ]);

  // 状态样式类
  function getStatusClass(status: string) {
    switch (status) {
      case '正常':
        return 'status-normal';
      case '异常':
        return 'status-error';
      case '警告':
        return 'status-warning';
      default:
        return 'status-normal';
    }
  }

  function initArpeBarChart() {
    // if (arpeBarChartRef.value) {
    //   arpeBarChartInstance = echarts.init(arpeBarChartRef.value);
    //   arpeBarChartInstance.setOption(barChartOption);
    // }
  }
  function resizeArpeBarChart() {
    //arpeBarChartInstance?.resize();
  }
  onMounted(() => {
    nextTick(() => {
      initArpeBarChart();
    });
    window.addEventListener('resize', resizeArpeBarChart);
  });
  onUnmounted(() => {
    //arpeBarChartInstance?.dispose();
    window.removeEventListener('resize', resizeArpeBarChart);
  });

  // 下方表格显示字段顺序
  const simpleCols = ['coilNo', 'time', 'entryEff', 'processEff', 'reason', 'normalRate'];
  // 字段中文名映射
  const colLabelMap: Record<string, string> = {
    coilNo: '卷号',
    time: '时间',
    entryEff: '入口效率',
    processEff: '工艺效率',
    reason: '异常原因',
    normalRate: '正常率',
  };
  function getColLabel(col: string) {
    return colLabelMap[col] || col;
  }

  defineExpose({ getColLabel, colLabelMap, simpleCols });

  // 仪表盘实时数据
  const entrySpeed = ref(0);
  const processSpeed = ref(0);
  const skinpassSpeed = ref(0);
  const welderSpeed = ref(0);

  // 新增：日产量、月产量等数据
  const dailyProduction = ref({});
  const dailyTopProd = ref({});
  const monthProduction = ref({});
  const monthTopProd = ref({});
  const monthSet = ref({});
  const monthRate = ref({});
  const dayTop = ref<any>({});
  const monthTop = ref<any>({});
  const lastDayTop = ref<any>({});
  const lastMonthTop = ref<any>({});
  const hourData = ref<any[]>([]);

  function updateGauges() {
    const gaugeVals = [entrySpeed.value, skinpassSpeed.value, processSpeed.value, welderSpeed.value];
    gaugeVals.forEach((val, idx) => {
      if (gaugeInstances[idx]) {
        gaugeInstances[idx].setOption(getGaugeOption(val));
      }
    });
  }

  // 新增：获取日产量、月产量等数据（暂时注释，接口未开发，使用假数据）
  const getDayAMonthOut = async () => {
    // TODO: 接口开发完成后启用
    // try {
    //   const result = await request.post("/prod/queryProdDayAndMonth", {});
    //   if (result) {
    //     const { dayOut, monthOut, dayOutTop, monthOutTop, monthOutRate, monthOutSet } = result;
    //     dailyProduction.value = {
    //       value: dayOut,
    //       title: '日产量',
    //       needFormat: false
    //     };
    //     dailyTopProd.value = {
    //       value: dayOutTop,
    //       title: '日产记录',
    //       needFormat: false
    //     };
    //     monthProduction.value = {
    //       value: monthOut,
    //       title: '月产量',
    //       needFormat: false
    //     };
    //     monthTopProd.value = {
    //       value: monthOutTop,
    //       title: '月产记录',
    //       needFormat: false
    //     };
    //     monthSet.value = {
    //       value: monthOutSet,
    //       title: '月设定产量',
    //       needFormat: false
    //     };
    //     monthRate.value = {
    //       value: monthOutRate,
    //       title: '月完成率',
    //       needFormat: false,
    //       unit: '%'
    //     };
    //     dayTop.value = result.dayTop;
    //     monthTop.value = result.monthTop;
    //     lastDayTop.value = result.lastDayTop;
    //     lastMonthTop.value = result.lastMonthTop;
    //   }
    // } catch (e) {
    //   console.error('获取日产量月产量数据失败:', e);
    // }

    // 暂时使用假数据
    dailyProduction.value = {
      value: 2981,
      title: '日产量',
      needFormat: false,
    };
    dailyTopProd.value = {
      value: 10455,
      title: '日产记录',
      needFormat: false,
    };
    monthProduction.value = {
      value: 141172,
      title: '月产量',
      needFormat: false,
    };
    monthTopProd.value = {
      value: 214901,
      title: '月产记录',
      needFormat: false,
    };
    monthSet.value = {
      value: 198700,
      title: '月设定产量',
      needFormat: false,
    };
    monthRate.value = {
      value: 71,
      title: '月完成率',
      needFormat: false,
      unit: '%',
    };
  };

  // 新增：获取日产量和日产记录数据（使用新接口）
  const fetchTcmOutputRecord = async () => {
    try {
      console.log('========== 开始获取日产量和日产记录数据 ==========');
      const response = await acidRollingApi.tcmOutputRecord();
      console.log('✅ tcmOutputRecord 接口响应:', response);
      console.log('✅ response.data:', response?.data);
      console.log('✅ response.data.data:', response?.data?.data);

      if (response?.data?.data) {
        const data = response.data.data;
        const outputWtDay = data.outputWtDay;
        const outputWtMonth = data.outputWtMonth;

        console.log('✅ 解析数据:', {
          outputWtDay,
          outputWtMonth,
        });

        // 更新 statsCards 中的日产量和月产量
        // statsCards 结构: [日产量, 日产记录, 月产量, 月产记录, 月设定产量, 月完成率]
        if (outputWtDay !== undefined && outputWtDay !== null) {
          statsCards.value[0] = {
            label: '日产量',
            value: outputWtDay,
            suffix: '吨',
          };
          console.log(`✅ 更新日产量: ${outputWtDay} 吨`);
        }

        if (outputWtMonth !== undefined && outputWtMonth !== null) {
          statsCards.value[2] = {
            label: '月产量',
            value: outputWtMonth,
            suffix: '吨',
          };
          console.log(`✅ 更新月产量: ${outputWtMonth} 吨`);
        }
      } else {
        console.warn('⚠️ 接口返回数据为空');
      }

      console.log('========== 日产量和日产记录数据获取完成 ==========');
    } catch (error) {
      console.error('❌ 获取日产量和日产记录数据失败:', error);
    }
  };

  // 新增：获取小时产量数据（暂时注释，接口未开发，使用假数据）
  const getHourCount = async () => {
    // TODO: 接口开发完成后启用
    // try {
    //   const result = await request.post("/req/pdo/getCoilHourOut", {}, "TCM2280");
    //   if (result) {
    //     hourData.value = result;
    //   }
    // } catch (e) {
    //   console.error('获取小时产量数据失败:', e);
    // }

    // 暂时使用假数据
    hourData.value = [
      { hour: '08:00', output: 333 },
      { hour: '09:00', output: 285 },
      { hour: '10:00', output: 310 },
      { hour: '11:00', output: 295 },
      { hour: '12:00', output: 278 },
    ];
  };

  // async function fetchGaugeData() {
  //   try {
  //     const { data: res } = await axios.get('/rest/restApi?name=TCM2280_itemtag')
  //     entrySpeed.value = Number(res['M_010_011DS_ANS']) || 0
  //     processSpeed.value = Number(res['M_010_103NI']) || 0
  //     skinpassSpeed.value = Number(res['M_400_262NI']) || 0
  //     welderSpeed.value = Number(res['M_010_105NI']) || 0
  //     updateGauges()
  //   } catch (e) {}
  // }

  function formatPercent(val: number | string) {
    const num = Number(val);
    if (isNaN(num)) return '-';
    return num.toFixed(2) + '%';
  }

  // 步骤顺序定义
  interface UncoilerStep {
    key: string;
    name: string;
  }
  interface PieDataItem {
    name: string;
    value: number;
    realValue: number | null;
    standard?: number | null;
  }

  const uncoiler1Steps: UncoilerStep[] = [
    { key: 'porExpandTime', name: '开卷扩张' },
    { key: 'headToCutterTime', name: '头部到剪切' },
    { key: 'arriveWaitPosTime', name: '到达等待位' },
    { key: 'anotherheadToweldTime', name: '另一头到焊机' },
    { key: 'tailToweldTime', name: '尾部到焊机' },
    { key: 'finishedWeldTime', name: '焊接完成' },
    { key: 'startLooperTime', name: '活套启动' },
    { key: 'porShrinkTime', name: '开卷收缩' },
  ];

  const uncoiler2Steps: UncoilerStep[] = uncoiler1Steps;

  // 每段标准值(秒)，可根据实际业务调整
  const uncoilerStandardSeconds = [60, 80, 90, 70, 60, 80, 60]; // 7段

  // 1. 顶部声明标准值变量
  const diffTimeStandard = ref<any>({});

  // getDiffTime 调用已合并到主 onMounted 中

  // 3. PieDataItem类型补充standard字段
  // 4. 修改convertUncoilerDataToPie，注入标准值
  function convertUncoilerDataToPie(uncoilerData: Record<string, any>): PieDataItem[] {
    const pieData: PieDataItem[] = [];
    const steps = [
      { name: '剪切', startKey: 'headToCutterTime', endKey: 'arriveWaitPosTime', stdKey: 'diffArriveWait' },
      { name: '穿带', startKey: 'straightTimes', endKey: 'headToCutterTime', stdKey: 'diffHeadToCutter' },
      { name: '开卷', startKey: 'porExpandTime', endKey: 'straightTimes', stdKey: 'diffStraight' },
      { name: '装卷', startKey: 'porCarStartTimes', endKey: 'porExpandTime', stdKey: 'diffPorExpand' },
    ];
    const getTime = (key: string): number | null => {
      const timeStr = uncoilerData[key];
      if (!timeStr) return null;
      return new Date(timeStr).getTime();
    };

    const currentTime = Date.now(); // 获取当前系统时间

    for (const step of steps) {
      const startTime = getTime(step.startKey);
      const endTime = getTime(step.endKey);
      let diff: number | null = null;
      let displayName = step.name;

      if (startTime !== null && endTime !== null) {
        // 两个时间都有，正常计算差值
        diff = Math.abs(Math.floor((endTime - startTime) / 1000));
      } else if (startTime !== null && endTime === null) {
        // 只有开始时间，用系统时间计算运行时间
        diff = Math.abs(Math.floor((currentTime - startTime) / 1000));
        displayName = `${step.name}运行时间`;
      } else if (startTime === null && endTime !== null) {
        // 只有结束时间，用系统时间计算运行时间
        diff = Math.abs(Math.floor((endTime - currentTime) / 1000));
        displayName = `${step.name}运行时间`;
      }

      const std = Number(diffTimeStandard.value?.[step.stdKey]) || null;

      // 即使没有实际数据，也要显示标准时间
      // 只有当标准时间存在时才创建该项
      if (std !== null) {
        pieData.push({
          name: displayName,
          value: 1,
          realValue: diff,
          standard: std,
        });
      }
    }
    return pieData;
  }

  // 5. 修改convertWelderDataToPie，注入标准值
  function convertWelderDataToPie(welderData: Record<string, any>): PieDataItem[] {
    const pieData: PieDataItem[] = [];
    const steps = [
      { name: '带头到焊机-带尾到焊机', startKey: 'tailToweldTime', endKey: 'anotherheadToweldTime', stdKey: 'diffHeadToCutter' },
      { name: '焊接完成-焊机激活', startKey: 'activeWeldTimes', endKey: 'finishedWeldTime', stdKey: 'diffArriveWait' },
    ];
    const getTime = (key: string): number | null => {
      const timeStr = welderData[key];
      if (!timeStr) return null;
      return new Date(timeStr).getTime();
    };

    const currentTime = Date.now(); // 获取当前系统时间

    for (const step of steps) {
      const startTime = getTime(step.startKey);
      const endTime = getTime(step.endKey);
      let diff: number | null = null;
      let displayName = step.name;

      if (startTime !== null && endTime !== null) {
        // 两个时间都有，正常计算差值
        diff = Math.abs(Math.floor((endTime - startTime) / 1000));
      } else if (startTime !== null && endTime === null) {
        // 只有开始时间，用系统时间计算运行时间
        diff = Math.abs(Math.floor((currentTime - startTime) / 1000));
        displayName = `${step.name}运行时间`;
      } else if (startTime === null && endTime !== null) {
        // 只有结束时间，用系统时间计算运行时间
        diff = Math.abs(Math.floor((endTime - currentTime) / 1000));
        displayName = `${step.name}运行时间`;
      }

      const std = Number(diffTimeStandard.value?.[step.stdKey]) || null;
      pieData.push({
        name: displayName,
        value: 1,
        realValue: diff,
        standard: std,
      });
    }
    return pieData;
  }

  // 6. 修改pieOptionFromPieData，超标高亮，tooltip显示实际/标准/超标
  function pieOptionFromPieData(pieData: PieDataItem[], gray: boolean = false) {
    return {
      tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(0,24,48,0.8)',
        borderColor: '#00f6ff',
        borderWidth: 1,
        textStyle: { color: '#fff' },
        formatter: function (params: { data: PieDataItem }) {
          const data = params.data;
          if (data.realValue === null) {
            return `${data.name}<br/>实际：无数据<br/>标准：${data.standard ?? '-'}秒`;
          }
          const isOver = data.standard && data.realValue > data.standard;
          return `${data.name}<br/>实际：${data.realValue}秒<br/>标准：${data.standard ?? '-'}秒<br/>${
            isOver ? '<span style="color:#ff4d4f">超出标准</span>' : '<span style="color:#52c41a">正常</span>'
          }`;
        },
      },
      series: [
        {
          type: 'pie',
          radius: ['60%', '80%'],
          center: ['50%', '50%'],
          label: {
            show: true,
            color: '#fff',
          },
          labelLine: { show: false, length: 12, length2: 8 },
          data: pieData.map((item) => {
            let color = '#00c853'; // 默认绿色
            if (gray) {
              color = '#888';
            } else if (item.realValue === null) {
              color = '#888';
            } else if (item.standard && item.realValue > item.standard) {
              color = '#ff4d4f'; // 超标红色
            }
            return {
              ...item,
              itemStyle: { color },
            };
          }),
        },
      ],
    };
  }

  // 示例：假设uncoiler1Data/uncoiler2Data为接口返回对象
  const uncoiler1Data = {
    entid: 'D250543915T',
    porExpandTime: '2025-05-24 04:41:21',
    headToCutterTime: '2025-05-29 04:42:44',
    arriveWaitPosTime: '2025-05-24 04:43:23',
    anotherheadToweldTime: '2025-05-24 04:44:56',
    tailToweldTime: '2025-05-24 04:44:48',
    finishedWeldTime: '2025-05-24 04:46:04',
    startLooperTime: '2025-05-24 04:46:09',
    porShrinkTime: '2025-05-24 04:47:23',
  };
  const uncoiler2Data = uncoiler1Data; // 可替换为真实数据

  const pie1Data = convertUncoilerDataToPie(uncoiler1Data);
  const pie2Data = convertUncoilerDataToPie(uncoiler2Data);

  // 在initCharts或相关渲染函数中：
  // pie3/pie4为1#、2#开卷机时序跟踪
  // const pie3 = echarts.init(document.getElementById('pie3')!)
  // pie3.setOption(pieOptionFromPieData(pie1Data))
  // const pie4 = echarts.init(document.getElementById('pie4')!)
  // pie4.setOption(pieOptionFromPieData(pie2Data))

  // 新增：测试调用furnaceTempDynamicCtrlApi.getTableData
  const testFurnaceApi = async () => {
    const param = {
      action: 'get_tags',
      operator: 'abc ',
      terminal: 'FM_01',
      body: [
        {
          tagName: 'enSpeedSet',
          timestamp: 0,
        },
        {
          tagName: 'processSpeedSet',
          timestamp: 0,
        },
        {
          tagName: 'exSpeedset',
          timestamp: 0,
        },
      ],
    };
    try {
      const res = await furnaceTempDynamicCtrlApi.getTableData(param);
      console.log('furnaceTempDynamicCtrlApi.getTableData 返回：', res);
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getTableData');
        return;
      }
      console.error('furnaceTempDynamicCtrlApi.getTableData 调用失败:', e);
    }
  };

  onMounted(() => {
    // ... existing code ...
    testFurnaceApi(); // 新增：页面挂载时测试接口
    // ... existing code ...
  });

  // 假数据：三个设定值
  const entrySetValue = ref(0);
  const processSetValue = ref(0);
  const exportSetValue = ref(0);
  // 三个AI模式值：0 未启用，1 已启用，其它/空为不显示
  const entryAIMode = ref<number | null>(null);
  const processAIMode = ref<number | null>(null);
  const millAIMode = ref<number | null>(null);

  // 获取AI设定值接口
  async function fetchAISetValues() {
    const param = {
      action: 'get_tags',
      operator: 'abc',
      terminal: 'FM_01',
      body: [
        // 速度设定与AI模式相关标签
        { tagName: 'tcm_enSpeedAImodel', timestamp: 0 },
        { tagName: 'tcm_processSpeedAImodel', timestamp: 0 },
        { tagName: 'tcm_millSpeedAImodel', timestamp: 0 },
        { tagName: 'PLTCM_DIR.EntSpeed', timestamp: 0 },
        { tagName: 'PLTCM_DIR.ProcessSpeed', timestamp: 0 },
        { tagName: 'PLTCM_DIR.TandemSpeed', timestamp: 0 },
        { tagName: 'tcm_por1_len', timestamp: 0 },
        { tagName: 'tcm_por2_len', timestamp: 0 },
      ],
    };
    try {
      const res = await rollingSimulationApi.HMI(param, { signal: controller.signal });
      // 假设返回数据结构为 { data: { PLTCM_DIR.EntSpeed: xxx, PLTCM_DIR.ProcessSpeed: xxx, PLTCM_DIR.TandemSpeed: xxx } }
      if (res && res.data) {
        // 将结果按 tagName 建立索引，避免依赖顺序
        const results = Array.isArray(res.data.results) ? res.data.results : [];
        const resultMap = new Map<string, any>();
        results.forEach((r: any) => {
          if (r && r.tagName !== undefined) {
            resultMap.set(String(r.tagName), r.value);
          }
        });

        // 三个AI模式赋值并打印
        entryAIMode.value =
          resultMap.get('tcm_enSpeedAImodel') === 0 || resultMap.get('tcm_enSpeedAImodel') === 1 ? Number(resultMap.get('tcm_enSpeedAImodel')) : null;
        processAIMode.value =
          resultMap.get('tcm_processSpeedAImodel') === 0 || resultMap.get('tcm_processSpeedAImodel') === 1
            ? Number(resultMap.get('tcm_processSpeedAImodel'))
            : null;
        millAIMode.value =
          resultMap.get('tcm_millSpeedAImodel') === 0 || resultMap.get('tcm_millSpeedAImodel') === 1
            ? Number(resultMap.get('tcm_millSpeedAImodel'))
            : null;
        console.log('[AI模式] 入口速度设定AI模式(tcm_enSpeedAImodel):', entryAIMode.value);
        console.log('[AI模式] 工艺速度设定AI模式(tcm_processSpeedAImodel):', processAIMode.value);
        console.log('[AI模式] 轧机速度设定AI模式(tcm_millSpeedAImodel):', millAIMode.value);

        // 原有速度/剩余长度取值（向后兼容）
        entrySetValue.value = Math.round(Number(resultMap.get('PLTCM_DIR.EntSpeed')) || 0);
        processSetValue.value = Math.round(Number(resultMap.get('PLTCM_DIR.ProcessSpeed')) || 0);
        exportSetValue.value = Math.round(Number(resultMap.get('PLTCM_DIR.TandemSpeed')) || 0);
        por1Len.value = Math.round(Number(resultMap.get('tcm_por1_len')) || 0);
        por2Len.value = Math.round(Number(resultMap.get('tcm_por2_len')) || 0);
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: fetchAISetValues');
        return;
      }
      console.error('AI设定值接口调用失败', e);
    }
  }

  let aiSetInterval: any = null;

  onMounted(() => {
    fetchAISetValues();
    timers.ai = setInterval(() => {
      fetchAISetValues();
    }, 5000);
  });

  // AI设定值定时器清理已合并到主清理函数中

  // SVG热点卡片内容
  const svgHotspotInfo = {
    hotspot1: `<div style='min-width:180px;'>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>DS间隙 <span style='color:#00eaff;'>1.24</span></div>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>OS间隙 <span style='color:#00eaff;'>1.22</span></div>
    <div style='margin-top:8px;'>
      <button style='background:#d64444;color:#fff;border:none;border-radius:4px;padding:2px 12px;margin-right:8px;'>Open</button>
      <button style='background:#3a8bff;color:#fff;border:none;border-radius:4px;padding:2px 12px;margin-right:8px;'>Relax</button>
      <button style='background:#444;color:#fff;border:none;border-radius:4px;padding:2px 12px;'>Closed</button>
    </div>
  </div>`,
    hotspot2: `<div style='min-width:180px;'>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>设定 <span style='color:#00eaff;'>0.00%</span></div>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>实测 <span style='color:#00eaff;'>0.00%</span></div>
    <div style='margin-top:8px;'>
      <button style='background:#d64444;color:#fff;border:none;border-radius:4px;padding:2px 12px;margin-right:8px;'>Open</button>
      <button style='background:#3a8bff;color:#fff;border:none;border-radius:4px;padding:2px 12px;margin-right:8px;'>Relax</button>
      <button style='background:#444;color:#fff;border:none;border-radius:4px;padding:2px 12px;'>Closed</button>
    </div>
  </div>`,
    hotspot3: `<div style='min-width:180px;'>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>上压力 <span style='color:#00eaff;'>1.23%</span></div>
    <div style='font-size:16px;font-weight:bold;margin-bottom:6px;'>下压力 <span style='color:#00eaff;'>1.24%</span></div>
  </div>`,
  };

  // 活套套量百分比（假设这三个变量已在数据获取时赋值，单位0-100）
  const inletLooperPercent = ref(0);
  const middleLooperPercent = ref(0);
  const exportLooperPercent = ref(0);

  // 立方体最大高度和底部y坐标（与svg中rect一致，需与svg实际参数保持一致）
  const cubeMaxHeight = 132; // 例如svg中height=132
  const cubeBaseY = 39; // 例如svg中y=39

  // 自动联动svg立方体液位填充
  function updateCubeFill() {
    const svg = document.querySelector('.svg-area svg') as SVGSVGElement;
    if (!svg) return;

    // 入口立方体
    const inletRect = svg.getElementById('inlet-cube-fill') as SVGRectElement;
    if (inletRect) {
      let percent = Number(inletLooperPercent.value);
      if (isNaN(percent) || percent < 0) percent = 0;
      if (percent > 100) percent = 100;
      const cubeMaxHeight = 13;
      const cubeBaseY = 187;
      let fillHeight = (cubeMaxHeight * percent) / 100;
      if (percent === 0) fillHeight = 0;
      let y = cubeBaseY + (cubeMaxHeight - fillHeight);
      if (percent === 0) y = cubeBaseY + cubeMaxHeight;
      inletRect.setAttribute('height', String(fillHeight));
      inletRect.setAttribute('y', String(y));
      console.log('inlet-cube-fill', { percent, fillHeight, y });
    }
    // 中间立方体
    const middleRect = svg.getElementById('middle-cube-fill') as SVGRectElement;
    if (middleRect) {
      let percent = Number(middleLooperPercent.value);
      if (isNaN(percent) || percent < 0) percent = 0;
      if (percent > 100) percent = 100;
      const cubeMaxHeight = 132;
      const cubeBaseY = 39;
      let fillHeight = (cubeMaxHeight * percent) / 100;
      if (percent === 0) fillHeight = 0;
      let y = cubeBaseY + (cubeMaxHeight - fillHeight);
      if (percent === 0) y = cubeBaseY + cubeMaxHeight;
      middleRect.setAttribute('height', String(fillHeight));
      middleRect.setAttribute('y', String(y));
      console.log('middle-cube-fill', { percent, fillHeight, y });
    }
    // 出口立方体
    const exportRect = svg.getElementById('export-cube-fill') as SVGRectElement;
    if (exportRect) {
      let percent = Number(exportLooperPercent.value);
      if (isNaN(percent) || percent < 0) percent = 0;
      if (percent > 100) percent = 100;
      const cubeMaxHeight = 35;
      const cubeBaseY = 60;
      let fillHeight = (cubeMaxHeight * percent) / 100;
      if (percent === 0) fillHeight = 0;
      let y = cubeBaseY + (cubeMaxHeight - fillHeight);
      if (percent === 0) y = cubeBaseY + cubeMaxHeight;
      exportRect.setAttribute('height', String(fillHeight));
      exportRect.setAttribute('y', String(y));
      console.log('export-cube-fill', { percent, fillHeight, y });
    }
  }

  // 监听百分比变化和svg加载，自动更新液位
  watch([inletLooperPercent, middleLooperPercent, exportLooperPercent], () => {
    nextTick(() => updateCubeFill());
  });

  // svg加载后也要更新一次
  onMounted(() => {
    nextTick(() => {
      updateCubeFill();
      // 兼容svg异步渲染，延迟多次尝试
      setTimeout(updateCubeFill, 500);
      setTimeout(updateCubeFill, 1000);
    });
  });

  // 重焊统计表格数据
  const reWeldTableData = ref<any[]>([]);

  // 通用时间格式化函数，支持10位自定义格式和标准时间字符串
  function formatToSecond(val: string): string {
    if (!val) return '-';
    // 处理2025070309这类自定义格式
    if (/^\d{10}$/.test(val)) {
      const year = val.slice(0, 4);
      const month = val.slice(4, 6);
      const day = val.slice(6, 8);
      const hour = val.slice(8, 10);
      return `${year}-${month}-${day} ${hour}:00:00`;
    }
    // 处理标准时间字符串
    const date = new Date(val);
    if (isNaN(date.getTime())) return val;
    const pad = (n: number) => n.toString().padStart(2, '0');
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
      date.getSeconds()
    )}`;
  }

  async function fetchReWeldTableData() {
    try {
      const params = { weldTimes: 1 };
      const res = await acidRollingApi.getReWeldList(params, { signal: controller.signal });
      if (res?.data?.data && Array.isArray(res.data.data)) {
        reWeldTableData.value = res.data.data.map((item: any) => ({
          bentID: item.bentID,
          fentID: item.fentID,
          weldTimes: item.weldTimes,
          createTime: formatToSecond(item.createTime),
        }));
      } else {
        reWeldTableData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getReWeldList');
        return;
      }
      console.error('获取重焊统计数据失败:', e);
      reWeldTableData.value = [];
    }
  }

  onMounted(() => {
    fetchReWeldTableData();
  });

  const router = useRouter();

  function handleReweldRowClick(row: any) {
    if (row && row.bentID) {
      router.push({
        path: '/acidRollingProductionEfficiency/reWeldingFrequencyTraceability',
        query: {
          bentID: row.bentID,
          weldTimes: 1,
        },
      });
    }
  }

  // 异常剪切状态表格数据
  const abnormalCutTableData = ref<any[]>([]);

  // 页面加载时获取异常剪切状态数据
  onMounted(async () => {
    try {
      const res = await acidRollingApi.getAcidEfficiencyList({ cutTimes: 1 }, { signal: controller.signal });
      if (res?.data?.data && Array.isArray(res.data.data)) {
        abnormalCutTableData.value = res.data.data;
      } else {
        abnormalCutTableData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getAcidEfficiencyList');
        return;
      }
      abnormalCutTableData.value = [];
    }
  });

  function handleAbnormalCutRowClick(row: any) {
    if (row && row.entid) {
      router.push({
        path: '/acidRollingProductionEfficiency/productionschedulereport',
        query: {
          entid: row.entid,
          cutTimes: 1,
        },
      });
    }
  }

  let earlyWarningInterval: any = null;

  // 1. 在<script setup>中添加报警数据处理逻辑
  const earlyWarningList = ref<any[]>([]);
  const processWarningShowAll = ref(false);
  // 1. 增加切换主报警内容的逻辑
  const processWarningIndex = ref(0);
  const processWarnings = computed(() => earlyWarningList.value.filter((item) => item.area === '工艺段AI设定值'));
  const processWarningFirst = computed(() => processWarnings.value[processWarningIndex.value] || processWarnings.value[0]);
  const processWarningRest = computed(() => processWarnings.value.filter((_, idx) => idx !== processWarningIndex.value));
  function formatWarningText(item: any) {
    if (!item) return '';
    // 速度取整数
    const speed = item.speedSet !== undefined && item.speedSet !== null ? Math.round(Number(item.speedSet)) : '-';
    return `卷号: ${item.entID ?? '-'}，速度: ${speed}，时间: ${item.setTime ?? '-'}`;
  }
  function handleProcessWarningSelect(idx: number) {
    processWarningIndex.value = idx;
  }

  // 定时获取报警数据
  onMounted(() => {
    // ...原有定时器...
    earlyWarningInterval = setInterval(async () => {
      try {
        const res = await acidRollingApi.getEarlyWarning({}, { signal: controller.signal });
        if (res && res.data && Array.isArray(res.data.data)) {
          earlyWarningList.value = res.data.data;
        } else {
          earlyWarningList.value = [];
        }
      } catch (e: any) {
        if (axios.isCancel(e)) {
          console.log('Request canceled: getEarlyWarning');
          return;
        }
        earlyWarningList.value = [];
      }
    }, 5000);
  });
  onUnmounted(() => {
    if (earlyWarningInterval) clearInterval(earlyWarningInterval);
    controller.abort();
  });

  // 新增入口段报警内容相关
  const entryWarningIndex = ref(0);
  const entryWarnings = computed(() => earlyWarningList.value.filter((item) => item.area === '入口段AI设定值'));
  const entryWarningFirst = computed(() => entryWarnings.value[entryWarningIndex.value] || entryWarnings.value[0]);
  const entryWarningRest = computed(() => entryWarnings.value.filter((_, idx) => idx !== entryWarningIndex.value));
  function handleEntryWarningSelect(idx: number) {
    entryWarningIndex.value = idx;
  }
  // 新增出口段报警内容相关
  const exportWarningIndex = ref(0);
  const exportWarnings = computed(() => earlyWarningList.value.filter((item) => item.area === '出口段AI设定值'));
  const exportWarningFirst = computed(() => exportWarnings.value[exportWarningIndex.value] || exportWarnings.value[0]);
  const exportWarningRest = computed(() => exportWarnings.value.filter((_, idx) => idx !== exportWarningIndex.value));
  function handleExportWarningSelect(idx: number) {
    exportWarningIndex.value = idx;
  }
  // 进度条区段数据，和SVG联动
  const progressSegments = ref<{ percent: number; color: string; coilId?: string; label?: string }[]>([]);

  // 新增：进度条悬浮卡片逻辑
  const hoveredSegmentIndex = ref<number | null>(null);
  function handleSegmentMouseEnter(idx: number) {
    hoveredSegmentIndex.value = idx;
  }
  function handleSegmentMouseLeave() {
    hoveredSegmentIndex.value = null;
  }

  // 圆盘剪时序跟踪数据
  const discShearPieData = ref<any[]>([]);

  // 获取圆盘剪时序数据，参数与getAcidEfficiency一致
  async function fetchDiscShearPieData() {
    const entid = coilIds.value?.coilIds?.[1] || '';
    if (!entid) {
      discShearPieData.value = [];
      return;
    }
    try {
      const res = await acidRollingApi.getAcidEfficiencyList({ entid }, { signal: controller.signal });
      if (res?.data?.data && Array.isArray(res.data.data) && res.data.data.length > 0) {
        const d = res.data.data[0];
        discShearPieData.value = [
          { name: '焊缝到挖边剪切', value: 1, realValue: d.notchTime },
          { name: '焊缝到圆盘剪', value: 1, realValue: d.arriceTrTime },
          { name: '圆盘剪调整', value: 1, realValue: d.weldAdjustGapTime },
        ];
      } else {
        discShearPieData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getAcidEfficiencyList');
        return;
      }
      discShearPieData.value = [];
    }
  }

  // 页面挂载和定时器中都调用
  onMounted(() => {
    fetchDiscShearPieData();
  });

  // 在所有定时器（如intervalId）中加入fetchDiscShearPieData
  // ...在intervalId = setInterval(() => { ... })里加：
  // fetchDiscShearPieData();

  // pie1渲染用pieOptionFromPieData
  watch(discShearPieData, () => {
    const pie1Inst = echarts.getInstanceByDom(document.getElementById('pie1') as HTMLElement);
    if (pie1Inst) pie1Inst.setOption(pieOptionFromPieData(discShearPieData.value));
  });

  // 停机信息录入表格数据
  const shutdownTableData = ref<any[]>([]);

  // 换辊统计表格数据
  const rollChangeTableData = ref<any[]>([]);

  // 获取停机信息数据
  async function fetchShutdownTableData() {
    try {
      const param = {
        pageIndex: 1,
        pageSize: 10, // 只获取最新的3条记录
        dbegin: '', // 不限制时间范围，获取最新数据
        dend: '',
      };
      const res = await showdownApi.getTbDowntimeTcm2280(param, { signal: controller.signal });
      if (res?.data?.status === 2000 && Array.isArray(res.data.data)) {
        shutdownTableData.value = res.data.data.map((item: any) => {
          // 转换停机时长从秒到分钟
          const durationInMinutes = item.duration ? Math.round((item.duration / 60) * 100) / 100 : 0;
          return {
            hotCoilId: item.hotCoilId || '-',
            duration: durationInMinutes,
            stopType: item.stopType || '-',
            stopStartTime: formatToSecond(item.stopStartTime),
            stopEndTime: formatToSecond(item.stopEndTime),
            // 保留原始时间用于跳转
            originalStartTime: item.stopStartTime || '',
            originalEndTime: item.stopEndTime || '',
            reason: item.reason || '-',
            respon: item.respon || '-',
            stopB: item.stopB || '-',
            stopS: item.stopS || '-',
            remark: item.remark || '-',
          };
        });
      } else {
        shutdownTableData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getTbDowntimeTcm2280');
        return;
      }
      console.error('获取停机信息数据失败:', e);
      shutdownTableData.value = [];
    }
  }

  // 获取换辊统计数据
  async function fetchRollChangeTableData() {
    try {
      const param = {
        pageIndex: 1,
        pageSize: 10, // 获取最新的10条记录
        startDate: '', // 不限制时间范围，获取最新数据
        endDate: '',
      };
      const res = await acidRollingApi.getRollChange(param, { signal: controller.signal });
      if (res?.data?.data && Array.isArray(res.data.data)) {
        rollChangeTableData.value = res.data.data.map((item: any) => {
          return {
            rollerNO: item.rollerNO || '-', // 上辊辊号
            loadTime: formatToSecond(item.loadTime), // 换辊时间标准格式
            rollType: item.rollType || '-', // 辊类型
            // 其它字段可按需保留
          };
        });
      } else {
        rollChangeTableData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getRollChange');
        return;
      }
      console.error('获取换辊统计数据失败:', e);
      rollChangeTableData.value = [];
    }
  }

  // 处理停机信息行点击
  function handleShutdownRowClick(row: any) {
    if (row && row.hotCoilId) {
      router.push({
        path: '/acidRollingProductionEfficiency/shutdownStatistics',
        query: {
          hotCoilId: row.hotCoilId,
          startTime: row.originalStartTime || row.stopStartTime,
          endTime: row.originalEndTime || row.stopEndTime,
        },
      });
    }
  }

  // 处理换辊统计行点击
  function handleRollChangeRowClick(row: any) {
    if (row && row.rollerNO) {
      router.push({
        path: '/acidRollingProductionEfficiency/rollchange',
        query: {
          rollerNO: row.rollerNO,
        },
      });
    }
  }

  // 格式化换辊时间字符串（如2025070309→2025-07-03 09:00）
  function formatRollChangeTime(val: string): string {
    if (!val || val.length < 10) return val || '-';
    const year = val.slice(0, 4);
    const month = val.slice(4, 6);
    const day = val.slice(6, 8);
    const hour = val.slice(8, 10);
    return `${year}-${month}-${day} ${hour}:00`;
  }

  // 自动横向滚动相关
  const scrollInterval = ref<any>(null);
  function handleTableMouseMove(e: MouseEvent) {
    const container = e.currentTarget as HTMLElement;
    // 找到 el-table 的 body 容器
    const body = container.querySelector('.el-table__body-wrapper') as HTMLElement;
    if (!body) return;

    const rect = container.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const edgeSize = 30; // px
    const scrollSpeed = 4; // px per tick

    // 清除之前的定时器
    if (scrollInterval.value) {
      clearInterval(scrollInterval.value);
      scrollInterval.value = null;
    }

    if (x > rect.width - edgeSize) {
      // 靠近右边
      scrollInterval.value = setInterval(() => {
        body.scrollLeft += scrollSpeed;
      }, 16);
    } else if (x < edgeSize) {
      // 靠近左边
      scrollInterval.value = setInterval(() => {
        body.scrollLeft -= scrollSpeed;
      }, 16);
    }
  }
  function handleTableMouseLeave() {
    if (scrollInterval.value) {
      clearInterval(scrollInterval.value);
      scrollInterval.value = null;
    }
  }
  onUnmounted(() => {
    if (scrollInterval.value) clearInterval(scrollInterval.value);
  });

  // 新增：右侧小卡片显示卷号
  const por1CoilNo = ref('');
  const por2CoilNo = ref('');
  const welderCoilNo = ref('');

  async function updatePorCoilNos() {
    try {
      const res2 = await rollingSimulationApi.rest({ name: 'TCM2280_zonetrk' }, { signal: controller.signal });
      por1CoilNo.value = res2?.data?.por1CoilNo || '';
      por2CoilNo.value = res2?.data?.por2CoilNo || '';

      // 根据por字段设置焊机卷号
      const por = res2?.data?.por;
      if (por === '1') {
        welderCoilNo.value = por1CoilNo.value;
      } else if (por === '2') {
        welderCoilNo.value = por2CoilNo.value;
      } else {
        welderCoilNo.value = '';
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: updatePorCoilNos');
        return;
      }
      por1CoilNo.value = '';
      por2CoilNo.value = '';
      welderCoilNo.value = '';
    }
  }

  onMounted(() => {
    updatePorCoilNos();
    timers.por = setInterval(updatePorCoilNos, 2000);
  });

  // 1. 新增uncoilerAbnormalTableData响应式变量
  const uncoilerAbnormalTableData = ref<any[]>([]);

  // 2. 获取开卷机异常统计数据
  async function fetchUncoilerAbnormalTableData() {
    try {
      const res = await acidRollingApi.getUncoiler({}, { signal: controller.signal });
      if (res?.data?.data && Array.isArray(res.data.data)) {
        uncoilerAbnormalTableData.value = res.data.data.map((item: any) => {
          // 时间差计算函数
          function diffSec(a: string, b: string) {
            if (!a || !b) return '-';
            const t1 = new Date(a).getTime();
            const t2 = new Date(b).getTime();
            if (isNaN(t1) || isNaN(t2)) return '-';
            return Math.abs(Math.floor((t2 - t1) / 1000));
          }
          return {
            entID: item.entID,
            load: diffSec(item.porCarStartTimes, item.porExpandTime),
            expand: diffSec(item.porExpandTime, item.straightTimes),
            straight: diffSec(item.straightTimes, item.headToCutterTime),
            cut: diffSec(item.headToCutterTime, item.arriveWaitPosTime),
          };
        });
      } else {
        uncoilerAbnormalTableData.value = [];
      }
    } catch (e: any) {
      if (axios.isCancel(e)) {
        console.log('Request canceled: getUncoiler');
        return;
      }
      uncoilerAbnormalTableData.value = [];
    }
  }

  // 3. 页面挂载时请求
  onMounted(() => {
    fetchUncoilerAbnormalTableData();
  });

  // 4. 渲染到"开卷机异常统计"表格
  // 找到tableList，找到title为"开卷机异常统计"的表格，替换其data为uncoilerAbnormalTableData
  // const uncoilerTableIndex = tableList.findIndex(tb => tb.title === '开卷机异常统计');
  // if (uncoilerTableIndex !== -1) {
  //   tableList[uncoilerTableIndex].data = uncoilerAbnormalTableData;
  // }

  // 横向拖拽滚动增强
  const arpeTablesWrapperRef = ref<HTMLElement | null>(null);
  const isDragging = ref(false);
  let dragStartX = 0;
  let dragStartScrollLeft = 0;
  let isDown = false;

  onMounted(() => {
    const el = arpeTablesWrapperRef.value;
    if (!el) return;
    const onMouseDown = (e: MouseEvent) => {
      if (e.button !== 0) return;
      isDown = true;
      isDragging.value = true;
      dragStartX = e.pageX;
      dragStartScrollLeft = el.scrollLeft;
      el.style.cursor = 'grabbing';
      document.body.style.userSelect = 'none';
      e.preventDefault();
    };
    const onMouseMove = (e: MouseEvent) => {
      if (!isDown) return;
      const dx = e.pageX - dragStartX;
      el.scrollLeft = dragStartScrollLeft - dx;
    };
    const onMouseUp = () => {
      isDown = false;
      isDragging.value = false;
      el.style.cursor = 'grab';
      document.body.style.userSelect = '';
    };
    el.addEventListener('mousedown', onMouseDown, { capture: true });
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);

    onUnmounted(() => {
      el.removeEventListener('mousedown', onMouseDown, { capture: true });
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    });
  });

  // ... existing code ...
  // 横向拖拽滚动增强
  // const arpeTablesWrapperRef = ref<HTMLElement | null>(null);
  // const isDragging = ref(false);
  // let dragStartX = 0;
  // let dragStartScrollLeft = 0;
  // let isDown = false;

  onMounted(() => {
    // 只针对"停机信息录入"表格内容区
    nextTick(() => {
      const tableScroll = document.querySelector('.arpe-table-scroll-x .el-table__body-wrapper') as HTMLElement;
      if (!tableScroll) return;
      let isDown = false;
      let startX = 0;
      let scrollLeft = 0;

      const onMouseDown = (e: MouseEvent) => {
        if (e.button !== 0) return;
        isDown = true;
        startX = e.pageX;
        scrollLeft = tableScroll.scrollLeft;
        tableScroll.style.cursor = 'grabbing';
        document.body.style.userSelect = 'none';
        e.preventDefault();
      };
      const onMouseMove = (e: MouseEvent) => {
        if (!isDown) return;
        const dx = e.pageX - startX;
        tableScroll.scrollLeft = scrollLeft - dx;
      };
      const onMouseUp = () => {
        isDown = false;
        tableScroll.style.cursor = 'grab';
        document.body.style.userSelect = '';
      };
      tableScroll.addEventListener('mousedown', onMouseDown);
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);

      onUnmounted(() => {
        tableScroll.removeEventListener('mousedown', onMouseDown);
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
      });
      // 初始小手
      tableScroll.style.cursor = 'grab';
    });
  });
  // ... existing code ...

  // 新增：1#、2#开卷机剩余长度
  const por1Len = ref(0);
  const por2Len = ref(0);

  // 统一销毁函数
  function destroyAllTasks() {
    // 清理所有定时器
    if (intervalId) clearInterval(intervalId);
    if (aiSetInterval) clearInterval(aiSetInterval);
    if (earlyWarningInterval) clearInterval(earlyWarningInterval);
    if (scrollInterval.value) clearInterval(scrollInterval.value);
    // 销毁所有echarts实例
    disposeGauges();
    disposeCharts && disposeCharts();
    // 移除所有事件监听
    window.removeEventListener('resize', resizeGauges);
    window.removeEventListener('resize', resizeArpeBarChart);
    // 终止所有请求
    controller.abort();
  }

  // 在onUnmounted和onBeforeUnmount都调用，确保彻底销毁
  onUnmounted(() => {
    destroyAllTasks();
  });
  onBeforeUnmount(() => {
    destroyAllTasks();
  });

  // ... existing code ...
  onMounted(() => {
    // 主流程优先加载
    fetchAISetValues();
    fetchGaugeData();
    fetchReWeldTableData();
    fetchShutdownTableData();
    fetchRollChangeTableData();
    fetchUncoilerAbnormalTableData();
    // ...其它主流程...

    // 懒加载 acidEfficiency 相关接口
    setTimeout(() => {
      fetchDiscShearPieData();
    }, 2000); // 2秒后再加载
  });
  // ... existing code ...

  // 在<script setup lang="ts">顶部添加三个ref用于存储最大设定值
  const inletLooperMaxSet = ref(0);
  const middleLooperMaxSet = ref(0);
  const exportLooperMaxSet = ref(0);

  // 本地产量/达成率柱折图（迁移自 prodBarLine.vue）
  const prodBarLineLocalRef = ref<HTMLElement | null>(null);
  let prodBarLineLocalInst: echarts.ECharts | null = null;

  // 新增：生产效率监控图表数据
  const productionEfficiencyChartRef = ref<HTMLElement | null>(null);
  let productionEfficiencyChartInst: echarts.ECharts | null = null;
  const productionEfficiencyDateType = ref<string>('hour');

  // 生产效率图表数据
  const productionEfficiencyHours = ref<string[]>(['4:00', '5:00', '6:00', '7:00', '8:00', '9:00', '10:00', '11:00', '12:00', '13:00']);
  const predictedProduction = ref<number[]>([12, 15, 14, 16, 18, 17, 19, 20, 18, 16]);
  const actualProduction = ref<number[]>([13, 16, 15, 17, 19, 18, 20, 21, 19, 17]);
  const achievementRate = ref<number[]>([108, 107, 107, 106, 106, 106, 105, 105, 106, 106]);

  function initProdBarLineLocal() {
    if (!prodBarLineLocalRef.value) return;
    if (!prodBarLineLocalInst) {
      prodBarLineLocalInst = echarts.init(prodBarLineLocalRef.value);
    }
    const option = {
      title: { text: '', left: 'center' },
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'cross' },
        appendToBody: true,
        position: function (point: any) {
          return [point[0], point[1] + 20];
        },
        formatter: function (params: any) {
          if (!Array.isArray(params) || params.length === 0) return '';
          const dataIndex = params[0]?.dataIndex ?? 0;
          const categoryName = params[0]?.name ?? '';
          const byName: Record<string, any> = {} as any;
          for (const it of params) byName[it.seriesName] = it;
          const rows: { label: string; value: string }[] = [];
          const dot = (c: string) =>
            '<span style="display:inline-block;width:10px;height:10px;background-color:' + c + ';border-radius:50%;margin-right:5px;"></span>';
          const formatPercent = (val: number) => {
            const p = val <= 1 ? val * 100 : val;
            const n = Number(p);
            if (!Number.isFinite(n)) return '-%';
            const s = n.toFixed(2).replace(/\.00$/, '');
            return s + '%';
          };
          const targetColor = byName['预测产量']?.color || '#ff9c39';
          const actualColor = byName['实际产量']?.color || '#029cc7';
          const rateColor = byName['达成率']?.color || '#91cc75';
          const targetProd = millUnitTarget.value?.[dataIndex];
          const actualProd = millUnitActual.value?.[dataIndex];
          const targetRoll = millUnitTargetRollCounts.value?.[dataIndex];
          const actualRoll = millUnitActualRollCounts.value?.[dataIndex];
          if (targetProd !== undefined) rows.push({ label: `${dot(targetColor)}预测产量`, value: String(targetProd) });
          if (actualProd !== undefined) rows.push({ label: `${dot(actualColor)}实际产量`, value: String(actualProd) });
          if (targetRoll !== undefined) rows.push({ label: `${dot(targetColor)}预测生产卷数`, value: String(targetRoll) });
          if (actualRoll !== undefined) rows.push({ label: `${dot(actualColor)}实际生产卷数`, value: String(actualRoll) });
          if (byName['达成率']) rows.push({ label: `${dot(rateColor)}达成率`, value: formatPercent(Number(byName['达成率'].value)) });
          const table =
            '<table style="border-collapse:collapse;">' +
            rows
              .map(
                (r) =>
                  `<tr><td style="padding:0 10px 0 0;white-space:nowrap;">${r.label}</td><td style="text-align:right;white-space:nowrap;">${r.value}</td></tr>`
              )
              .join('') +
            '</table>';
          return (categoryName ? categoryName + '<br/>' : '') + table;
        },
      },
      grid: { left: 28, right: 40, top: 26, bottom: 28, containLabel: true },
      legend: {
        data: ['预测产量', '实际产量', '达成率'],
        top: 0,
        textStyle: { color: '#ffffff', fontSize: 14 },
        itemWidth: 10,
        itemHeight: 8,
      },
      xAxis: {
        type: 'category',
        boundaryGap: true,
        data: millUnitX.value,
        axisLine: { lineStyle: { color: 'rgba(78,207,255,0.5)' } },
        axisLabel: { color: '#ffffff', fontSize: 13 },
      },
      yAxis: [
        {
          type: 'value',
          name: '产量',
          axisLine: { lineStyle: { color: 'rgba(78,207,255,0.5)' } },
          axisLabel: { color: '#ffffff', fontSize: 13 },
          splitLine: { lineStyle: { color: 'rgba(78,207,255,0.12)', type: 'dashed' } },
        },
        {
          type: 'value',
          name: '达成率',
          axisLine: { lineStyle: { color: 'rgba(255,107,107,0.6)' } },
          axisLabel: { color: '#ffffff', fontSize: 13 },
          splitLine: { show: false },
        },
      ],
      series: [
        {
          name: '预测产量',
          type: 'bar',
          data: millUnitTargetRollCounts.value,
          yAxisIndex: 0,
          barWidth: 20,
          itemStyle: { color: '#ff9c39', borderRadius: [8, 8, 8, 8], opacity: 0.9 },
        },
        {
          name: '实际产量',
          type: 'bar',
          data: millUnitActualRollCounts.value,
          yAxisIndex: 0,
          barWidth: 20,
          itemStyle: { color: '#029cc7', borderRadius: [8, 8, 8, 8], opacity: 0.9 },
        },
        {
          name: '达成率',
          type: 'line',
          data: millUnitAchiRate.value,
          yAxisIndex: 1,
          smooth: true,
          symbol: 'circle',
          symbolSize: 4,
          lineStyle: { color: '#91cc75', width: 2 },
        },
      ],
    } as any;
    prodBarLineLocalInst.setOption(option, true);
  }

  function updateProdBarLineLocal() {
    if (!prodBarLineLocalInst) return;
    initProdBarLineLocal();
  }

  watch(
    [millUnitX, millUnitTarget, millUnitActual, millUnitAchiRate],
    () => {
      updateProdBarLineLocal();
    },
    { deep: true }
  );

  watch(
    [millUnitTargetRollCounts, millUnitActualRollCounts],
    () => {
      updateProdBarLineLocal();
    },
    { deep: true }
  );

  // 新增：生产效率监控图表初始化
  function initProductionEfficiencyChart() {
    if (!productionEfficiencyChartRef.value) return;
    if (!productionEfficiencyChartInst) {
      productionEfficiencyChartInst = echarts.init(productionEfficiencyChartRef.value);
    }

    // 动态计算Y轴最大值，按功率/扭矩数据自动扩展
    const allBars: number[] = ([] as number[]).concat(predictedProduction.value || []).concat(actualProduction.value || []);
    const maxBar = allBars.length ? Math.max(...allBars) : 0;
    const axisMax = maxBar > 0 ? Math.ceil(maxBar * 1.2) : 10;

    const option = {
      title: { text: '', left: 'center' },
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' },
        appendToBody: true,
        backgroundColor: 'rgba(0, 0, 0, 0.8)',
        borderColor: '#00f6ff',
        borderWidth: 1,
        textStyle: { color: '#ffffff' },
        formatter: function (params: any) {
          if (!Array.isArray(params) || params.length === 0) return '';
          const categoryName = params[0]?.name ?? '';
          const byName: Record<string, any> = {};
          for (const it of params) byName[it.seriesName] = it;

          const rows: { label: string; value: string }[] = [];
          const dot = (c: string) =>
            '<span style="display:inline-block;width:10px;height:10px;background-color:' + c + ';border-radius:50%;margin-right:5px;"></span>';

          if (byName['功率实际值']) rows.push({ label: `${dot('#40bfff')}功率实际值`, value: String(byName['功率实际值'].value) });
          if (byName['电机扭矩实际值']) rows.push({ label: `${dot('#a97af8')}电机扭矩实际值`, value: String(byName['电机扭矩实际值'].value) });
          const table =
            '<table style="border-collapse:collapse;">' +
            rows
              .map(
                (r) =>
                  `<tr><td style="padding:0 10px 0 0;white-space:nowrap;">${r.label}</td><td style="text-align:right;white-space:nowrap;">${r.value}</td></tr>`
              )
              .join('') +
            '</table>';
          return (categoryName ? categoryName + '<br/>' : '') + table;
        },
      },
      grid: { left: 30, right: 20, top: 24, bottom: 26, containLabel: true },
      xAxis: {
        type: 'category',
        boundaryGap: true,
        data: productionEfficiencyHours.value,
        axisLine: { lineStyle: { color: 'rgba(78,207,255,0.5)' } },
        axisLabel: { color: '#b2eaff', fontSize: 12 },
        splitLine: { show: false },
      },
      yAxis: [
        {
          type: 'value',
          name: '',
          min: 0,
          max: axisMax,
          axisLine: { lineStyle: { color: 'rgba(78,207,255,0.5)' } },
          axisLabel: { color: '#b2eaff', fontSize: 12 },
          splitLine: {
            lineStyle: { color: 'rgba(78,207,255,0.12)', type: 'dashed' },
            show: true,
          },
        },
      ],
      series: [
        {
          name: '功率实际值',
          type: 'bar',
          data: predictedProduction.value,
          barWidth: 18,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#40bfff' },
              { offset: 1, color: 'rgba(64,191,255,0.35)' },
            ]),
            borderRadius: [6, 6, 0, 0],
            opacity: 0.95,
          },
        },
        {
          name: '电机扭矩实际值',
          type: 'bar',
          data: actualProduction.value,
          barWidth: 18,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#a97af8' },
              { offset: 1, color: 'rgba(169,122,248,0.35)' },
            ]),
            borderRadius: [6, 6, 0, 0],
            opacity: 0.95,
          },
        },
      ],
    } as any;

    productionEfficiencyChartInst.setOption(option, true);
  }

  function updateProductionEfficiencyChart() {
    if (!productionEfficiencyChartInst) return;
    initProductionEfficiencyChart();
  }

  // 监听数据变化
  watch(
    [productionEfficiencyHours, predictedProduction, actualProduction],
    () => {
      updateProductionEfficiencyChart();
    },
    { deep: true }
  );

  // 已去除对外部racksData的依赖，避免未定义报错

  // 在onMounted中初始化新图表
  onMounted(() => {
    nextTick(() => {
      initProdBarLineLocal();
      initProductionEfficiencyChart(); // 新增
    });
    window.addEventListener('resize', () => {
      if (prodBarLineLocalInst) prodBarLineLocalInst.resize();
      if (productionEfficiencyChartInst) productionEfficiencyChartInst.resize(); // 新增
    });
  });

  // 在onUnmounted中清理新图表
  onUnmounted(() => {
    if (prodBarLineLocalInst) {
      prodBarLineLocalInst.dispose();
      prodBarLineLocalInst = null;
    }
    if (productionEfficiencyChartInst) {
      // 新增
      productionEfficiencyChartInst.dispose();
      productionEfficiencyChartInst = null;
    }
  });

  // 同步左侧生产效率图表与右侧产量/达成率切换（仅依赖本页已定义的数据，避免未定义变量报错）
  watch(
    [millUnitX, millUnitTargetRollCounts, millUnitActualRollCounts, millUnitAchiRate],
    () => {
      try {
        productionEfficiencyHours.value = [...millUnitX.value];
        predictedProduction.value = [...millUnitTargetRollCounts.value];
        actualProduction.value = [...millUnitActualRollCounts.value];
        achievementRate.value = [...millUnitAchiRate.value];
        updateProductionEfficiencyChart();
      } catch {}
    },
    { deep: true }
  );
</script>

<style scoped lang="less">
  /* --- Base & Layout --- */
  .arpe-container {
    width: 100vw;
    height: 100vh;
    background: url('../../assets/images/body-bg.jpg') no-repeat center center;
    background-size: cover;
    color: #fff;
    font-family: 'Microsoft YaHei', Arial, sans-serif;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    margin-left: -14px;
  }

  .arpe-header {
    flex: 0 0 6vh;
    background-image: url('../../assets/images/head-bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 0.5vh;
    z-index: 10;
  }

  .arpe-title {
    font-size: 1.3vw;
    color: #ffffff;
    text-align: center;
    letter-spacing: 0.2vw;
  }

  .arpe-content-layout {
    flex: 1 1 0%;
    display: flex;
    flex-direction: row;
    width: 100vw;
    min-width: 0;
    min-height: 0;
    position: relative;
    align-items: stretch;
    margin-top: -3.5vh;
  }

  .arpe-side-rolls {
    width: 4vw;
    min-width: 44px;
    display: flex;
    flex-direction: column;
    align-items: center;
    position: absolute;
    z-index: 2;
    top: 20%;
    bottom: 0;
    justify-content: flex-start;
    height: 100%;
  }

  .arpe-side-rolls-left {
    left: 0;
  }

  .arpe-side-rolls-right {
    right: 0;
  }

  .arpe-roll-img-wrap {
    width: 3vw;
    min-width: 44px;
    height: 5vw;
    min-height: 70px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
  }

  .arpe-roll-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    opacity: 0.7;
    transition: opacity 0.3s;
  }

  .arpe-main {
    flex: 1 1 0%;
    display: flex;
    flex-direction: column;
    gap: 1.2vw;
    padding: 1.2vw 0 0 0;
    min-width: 0;
    min-height: 0;
    z-index: 1;
    margin: 0 4vw;
    .svg {
      width: 100%;
      height: 20vh;
      flex-shrink: 0;

      svg {
        width: 100%;
        height: 100%;
      }
    }
  }

  .arpe-row {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .arpe-row-top {
    min-height: 8vh;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1vw;
  }

  .arpe-row-gauges {
    min-height: 8vh;
    justify-content: center;
    align-items: flex-end;
    position: relative;
  }

  .arpe-gauges-panel {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    justify-content: center;
    width: 100%;
    gap: 0.1vw;
  }

  .arpe-gauge-img {
    width: 8vw;
    min-width: 70px;
    height: 7.5vw;
    min-height: 65px;
    display: block;
  }

  .arpe-lights-img {
    width: 82px;
    height: 199px;
    display: block;
    margin: 0 18px;
  }

  .arpe-icons-group {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    gap: 12px;
    margin: 0 18px;
  }

  .arpe-icon-img {
    width: 48px;
    height: 48px;
    display: block;
  }

  .arpe-row-progress {
    min-height: 4vh;
  }

  .arpe-row-charts {
    min-height: 9vh;
    padding: 4px 8px 0 8px;
    margin-bottom: 12px; /* 与下方区域拉开间距，避免覆盖 */
  }

  .arpe-row-alert {
    min-height: 3vh;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    gap: 1.2vw;
  }

  /* 占位样式，仅用于开发阶段，后续可去除 */
  .arpe-gauges-placeholder,
  .arpe-progress-placeholder,
  .arpe-charts-placeholder,
  .arpe-alert-placeholder,
  .arpe-tables-placeholder {
    width: 90%;
    min-height: 40px;
    background: rgba(0, 0, 0, 0.08);
    border: 1px dashed #4ecfff;
    color: #4ecfff;
    text-align: center;
    line-height: 40px;
    font-size: 18px;
    border-radius: 8px;
  }

  .gauge-container {
    width: 120px;
    height: 120px;
    margin: 0 8px;
    display: inline-block;
    background: none;
  }

  .arpe-gauge-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 0 2px;
  }

  .arpe-gauge-label {
    margin-top: 2px;
    font-size: 13px;
    color: #b2eaff;
    text-align: center;
    letter-spacing: 1px;
    text-shadow:
      0 0 4px #0ff,
      0 0 2px #000;
    line-height: 1.1;
  }

  .arpe-progress-bar-area {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    height: 6vh;
    box-sizing: border-box;
    overflow: visible;
    justify-content: center;
    margin-left: -20px;
  }

  .arpe-progress-bar-flex {
    display: flex;
    flex-direction: row;
    width: 100%;
    height: 2vh;
    align-items: center;
    position: relative;
  }

  .arpe-bar-rect {
    height: 2vh;
    min-height: 24px;
    margin: 0 0.1vw;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1vw;
    font-weight: bold;
    color: #fff;
    letter-spacing: 1px;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.08);
  }

  .arpe-bar-rect-done {
    background: linear-gradient(90deg, #7be16a 60%, #b6f7a7 100%);
  }

  .arpe-bar-rect-yellow {
    background: linear-gradient(90deg, #ffe066 60%, #fff7b2 100%);
    border: 0.2vw solid #ffb800;
    color: #333;
    font-size: 1.1vw;
  }

  .arpe-bar-rect-red {
    background: linear-gradient(90deg, #ff4d4f 60%, #ffb199 100%);
  }

  .arpe-bar-rect-blue {
    background: linear-gradient(90deg, #3a8bff 60%, #a0cfff 100%);
  }

  .arpe-bar-rect-done {
    background: linear-gradient(90deg, #7be16a 60%, #b6f7a7 100%);
  }

  .arpe-bar-rect-remain {
    background: linear-gradient(90deg, #ff4d4f 60%, #ffb199 100%);
  }

  .arpe-bar-rect-todo {
    background: linear-gradient(90deg, #b6f7a7 0%, #7be16a 100%);
  }

  .arpe-chart-group {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    width: 99%;
    gap: 0.6vw;
    flex-wrap: wrap;
    padding: 4px 6px 0 6px;
  }

  .arpe-chart-block {
    flex: 1 1 0;
    min-width: 180px;
    background: rgba(0, 24, 48, 0.3);
    border: 1px solid rgba(0, 246, 255, 0.2);
    border-radius: 0.8vw;
    padding: 0.8vw 0.5vw 0.5vw 0.5vw;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 0;
    box-shadow: 0 0 20px rgba(0, 246, 255, 0.1);
    backdrop-filter: blur(5px);
    transition: all 0.3s ease;
    position: relative; /* 添加相对定位 */
  }

  .arpe-chart-block:hover {
    box-shadow: 0 0 30px rgba(0, 246, 255, 0.2);
    border-color: rgba(0, 246, 255, 0.4);
  }

  .arpe-chart-title {
    color: #00f6ff;
    font-size: 0.95vw; /* 缩小字体 */
    text-align: center;
    margin-bottom: 0.18vw;
    letter-spacing: 1px;
    text-shadow: 0 0 8px #00f6ff;
    font-weight: 500;
    line-height: 1.1;
  }

  .arpe-chart {
    width: 12vw;
    min-width: 120px;
    height: 7.8vw;
    min-height: 88px;
    position: relative;
  }

  .arpe-chart::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(45deg, rgba(0, 246, 255, 0.05) 0%, rgba(0, 246, 255, 0) 100%);
    pointer-events: none;
  }

  .arpe-chart-legend {
    margin-top: 0.3vw;
    font-size: 0.9vw;
    color: #b2eaff;
    text-align: center;
    text-shadow: 0 0 4px #00f6ff;
  }

  /* 底部图表带布局 */
  .arpe-row-bottom-graph {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    height: 250px;
    min-height: 250px;
    padding: 6px 12px 0 12px;
    margin-top: 14px; /* 顶部留白 */
    box-sizing: border-box;
  }
  .arpe-bottom-right-bar {
    width: 36%;
    min-width: 420px;
    height: 100%;
    background: rgba(0, 24, 48, 0.22);
    border: 1px solid rgba(0, 246, 255, 0.2);
    border-radius: 10px;
    box-shadow: 0 0 12px rgba(0, 246, 255, 0.12);
    padding: 12px;
  }
  .bar-header {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 6px;
  }
  .arpe-bottom-right-bar__chart {
    width: 100%;
    height: 100%;
    min-height: 220px;
  }

  /* prodBarLine组件外部样式定制 - 匹配当前页面风格 */
  .prod-bar-line-chart {
    width: 100%;
    height: 100%;
    min-height: 180px;
    background: transparent;
  }

  /* 通过深度选择器修改ECharts内部样式 */
  .prod-bar-line-chart :deep(.chart-container) {
    background: transparent !important;
  }

  /* 修改图表标题样式 */
  .prod-bar-line-chart :deep(.echarts-title) {
    color: #00f6ff !important;
    font-size: 14px !important;
    font-weight: bold !important;
    text-shadow: 0 0 8px #00f6ff !important;
  }

  /* 修改图例样式 */
  .prod-bar-line-chart :deep(.echarts-legend) {
    color: #b2eaff !important;
    font-size: 14px !important;
  }

  /* 修改X轴样式 */
  .prod-bar-line-chart :deep(.echarts-axis-label) {
    color: #b2eaff !important;
    font-size: 13px !important;
  }

  /* 修改Y轴样式 */
  .prod-bar-line-chart :deep(.echarts-y-axis-label) {
    color: #b2eaff !important;
    font-size: 13px !important;
  }

  /* 修改Y轴（达成率）样式 */
  .prod-bar-line-chart :deep(.echarts-y-axis-right .echarts-axis-label) {
    color: #ffb3b3 !important;
    font-size: 13px !important;
  }

  /* 修改网格线样式 */
  .prod-bar-line-chart :deep(.echarts-grid-line) {
    stroke: rgba(78, 207, 255, 0.12) !important;
    stroke-dasharray: 5, 5 !important;
  }

  /* 修改轴线样式 */
  .prod-bar-line-chart :deep(.echarts-axis-line) {
    stroke: rgba(78, 207, 255, 0.5) !important;
  }

  .legend-dot {
    display: inline-block;
    width: 0.6vw;
    min-width: 8px;
    height: 0.8vw;
    min-height: 8px;
    border-radius: 50%;
    margin: 0 0.3vw 0 0.7vw;
    vertical-align: middle;
    box-shadow: 0 0 8px currentColor;
  }

  .legend-dot-blue {
    background: #00f6ff;
  }

  .legend-dot-green {
    background: #4ecfff;
  }

  .arpe-warning-banner {
    width: 48%;
    background-color: rgba(255, 77, 79, 0.85);
    color: #fff;
    padding: 0.3vw 1vw;
    font-size: 1.1vw;
    text-align: left;
    border: 1px solid #ea0f0f;
    box-shadow: 0 0 10px rgba(255, 77, 79, 0.5);
    border-radius: 0.6vw;
    display: flex;
    align-items: center;
    animation: arpe-flash 2s infinite;
    gap: 0.5vw;
  }

  .arpe-warning-banner-left {
    justify-content: flex-start;
    text-align: left;
  }

  .arpe-warning-banner-right {
    justify-content: flex-start;
    text-align: left;
  }

  @keyframes arpe-flash {
    0%,
    100% {
      opacity: 1;
    }

    50% {
      opacity: 0.7;
    }
  }

  .arpe-tables-wrapper {
    display: flex;
    flex-direction: row;
    gap: 8px;
    justify-content: flex-start;
    align-items: stretch;
    width: 100%;
    height: 220px;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 12px;
    /* 确保在较小屏幕上也能正常显示 */
    min-width: 1720px;
    cursor: grab;
  }

  .arpe-tables-wrapper.grabbing {
    cursor: grabbing !important;
  }

  /* 横向滚动条样式 */
  .arpe-tables-wrapper::-webkit-scrollbar {
    height: 12px;
  }

  .arpe-tables-wrapper::-webkit-scrollbar-track {
    background: #0f2142;
    border-radius: 6px;
    border: 1px solid #3a5a8a;
  }

  .arpe-tables-wrapper::-webkit-scrollbar-thumb {
    background: linear-gradient(90deg, #00f6ff 0%, #4ecfff 100%);
    border-radius: 6px;
    border: 1px solid #00f6ff;
    box-shadow: 0 0 8px rgba(0, 246, 255, 0.5);
  }

  .arpe-tables-wrapper::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(90deg, #4ecfff 0%, #00f6ff 100%);
    box-shadow: 0 0 12px rgba(0, 246, 255, 0.8);
  }

  .arpe-tables-wrapper::-webkit-scrollbar-corner {
    background: #0f2142;
  }

  .arpe-tables-wrapper::-webkit-scrollbar-button {
    width: 0;
    height: 0;
  }

  .arpe-tables-wrapper::-webkit-scrollbar-track-piece {
    background: #0f2142;
    border-radius: 6px;
  }

  .arpe-tables-wrapper::-webkit-scrollbar-corner {
    background: #0f2142;
  }

  .arpe-table-card {
    display: flex;
    flex-direction: column;
    background-color: rgba(28, 58, 99, 0.7);
    border: 1px solid rgba(90, 130, 190, 0.4);
    box-shadow: 0 0 15px rgba(11, 93, 209, 0.2);
    overflow: hidden;
    border-radius: 8px;
    min-width: 340px;
    max-width: 420px;
    width: 100%;
    height: 100%;
  }
  .arpe-table-header {
    background-image: url('../../assets/img/sub_title_bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    padding: 6px 15px;
    font-weight: bold;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(58, 90, 138, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 3.5vh;
    line-height: 3.5vh;
  }
  .arpe-table-header span {
    background-image: -webkit-linear-gradient(left, #0072ff, #00eaff, #01aaff);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    font-weight: bolder;
    font-size: 1.7vh;
  }
  .arpe-title-icon-left {
    margin-right: 1vw;
    transform: rotateY(180deg);
    width: 2vw;
    height: 3vh;
    background-image: url(/src/assets/images/title-icon-right.png);
    background-size: 100% 100%;
  }
  .arpe-title-icon-right {
    margin-left: 1vw;
    width: 2vw;
    height: 3vh;
    background-image: url(/src/assets/images/title-icon-right.png);
    background-size: 100% 100%;
  }
  .arpe-table-simple-list {
    flex-grow: 1;
    width: 100%;
    height: 100%;
    background-color: transparent !important;
    border: none !important;
  }

  .arpe-row-tables {
    :deep(.el-table) {
      background-color: transparent !important;
      border: none !important;
    }
    :deep(.el-table tr:nth-child(odd)) {
      background-color: #0f2142 !important;
    }
    :deep(.el-table tr:nth-child(even)) {
      background-color: #142a52 !important;
    }
    :deep(.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell) {
      background-color: rgba(66, 180, 255, 0.1) !important;
    }
    :deep(.el-table td.el-table__cell),
    :deep(.el-table th.el-table__cell) {
      background-color: transparent !important;
      border-color: #06279d !important;
      color: #c0c4cc;
    }
    :deep(.el-table th.el-table__cell) {
      color: #b8e8ff;
      background-color: #183272 !important;
      border-bottom: 1px solid #06279d !important;
    }
    :deep(.el-table--border .el-table__inner-wrapper::after),
    :deep(.el-table--border::after),
    :deep(.el-table--border::before),
    :deep(.el-table__border-left-patch),
    :deep(.el-table--border .el-table__inner-wrapper::before) {
      background-color: #06279d !important;
    }
    :deep(.el-table td.el-table__cell),
    :deep(.el-table th.el-table__cell.is-leaf) {
      border-bottom: 1px solid #06279d !important;
    }
    :deep(.el-table--border td.el-table__cell),
    :deep(.el-table--border th.el-table__cell) {
      border-right: 1px solid #06279d !important;
    }
    :deep(.el-table__body-wrapper) {
      scrollbar-width: thin;
      scrollbar-color: #3a5a8a #142a52;
    }
    :deep(.el-table__body-wrapper::-webkit-scrollbar) {
      width: 6px;
      height: 6px;
    }
    :deep(.el-table__body-wrapper::-webkit-scrollbar-track) {
      background: #142a52;
      border-radius: 3px;
    }
    :deep(.el-table__body-wrapper::-webkit-scrollbar-thumb) {
      background-color: #3a5a8a;
      border-radius: 3px;
    }
  }

  .arpe-ai-set-card {
    width: 180px;
    min-height: 54px;
    background: linear-gradient(135deg, rgba(10, 24, 48, 0.95) 0%, rgba(0, 246, 255, 0.13) 100%);
    border: 2px solid #00f6ff99;
    border-radius: 10px;
    box-shadow:
      0 0 12px #00f6ff33,
      0 0 8px #0ff2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 6px 8px;
    margin: 8px auto 0 auto;
    position: relative;
    z-index: 2;
    transition:
      box-shadow 0.25s,
      border-color 0.25s;
  }

  .arpe-ai-set-card2 {
    width: 160px;
    min-height: 54px;
    background: linear-gradient(135deg, rgba(10, 24, 48, 0.95) 0%, rgba(0, 246, 255, 0.13) 100%);
    border: 2px solid #00f6ff99;
    border-radius: 10px;
    box-shadow:
      0 0 12px #00f6ff33,
      0 0 8px #0ff2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 8px 10px 6px 10px;
    margin: 8px auto 0 auto;
    position: relative;
    z-index: 2;
    transition:
      box-shadow 0.25s,
      border-color 0.25s;
  }

  .arpe-ai-set-card-status {
    margin-bottom: 4px;
    display: flex;
    justify-content: center;
  }

  .arpe-ai-set-card-title {
    color: #00eaff;
    font-size: 13px;
    font-weight: bold;
    letter-spacing: 1px;
    margin-bottom: 2px;
    text-shadow: 0 0 8px #00f6ff;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* AI模式徽标 */
  .ai-mode-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    height: 20px;
    line-height: 20px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 1px;
    backdrop-filter: blur(2px);
    box-shadow:
      0 0 10px rgba(0, 238, 255, 0.2) inset,
      0 0 10px rgba(0, 238, 255, 0.08);
    border: 1px solid rgba(0, 238, 255, 0.25);
    transform: translateY(-1px);
    user-select: none;
  }
  .ai-mode-on {
    background: linear-gradient(90deg, rgba(0, 246, 255, 0.18) 0%, rgba(0, 180, 255, 0.12) 100%);
    color: #6fe3ff;
    border-color: rgba(0, 246, 255, 0.45);
    text-shadow: 0 0 8px rgba(0, 246, 255, 0.6);
  }
  .ai-mode-off {
    background: linear-gradient(90deg, rgba(255, 77, 79, 0.18) 0%, rgba(255, 77, 79, 0.1) 100%);
    color: #ff9a9b;
    border-color: rgba(255, 77, 79, 0.45);
    text-shadow: 0 0 8px rgba(255, 77, 79, 0.6);
  }
  .ai-mode-badge::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    box-shadow: 0 0 6px currentColor;
  }
  .ai-mode-on::before {
    background: #00eaff;
  }
  .ai-mode-off::before {
    background: #ff4d4f;
  }

  .arpe-ai-set-card-value {
    color: #fff;
    font-size: 18px;
    font-weight: bold;
    text-shadow: 0 0 12px #00f6ff99;
    margin-bottom: 0;
    text-align: center;
  }

  .arpe-ai-set-card-unit {
    font-size: 12px;
    color: #b2eaff;
    margin-left: 4px;
    opacity: 0.8;
  }

  /* 入口速度小卡片样式 */
  .arpe-small-info-card {
    width: 150px;
    min-height: 48px;
    background: linear-gradient(135deg, rgba(10, 24, 48, 0.95) 0%, rgba(0, 246, 255, 0.13) 100%);
    border: 2px solid #00f6ff99;
    border-radius: 10px;
    box-shadow:
      0 0 12px #00f6ff33,
      0 0 8px #0ff2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 6px 8px;
    color: #fff;
  }
  .arpe-small-info-title {
    color: #00eaff;
    font-size: 12px;
    letter-spacing: 1px;
    margin-bottom: 2px;
  }
  .arpe-small-info-value {
    font-size: 18px;
    font-weight: bold;
    text-shadow: 0 0 12px #00f6ff99;
  }
  .arpe-small-info-value .unit {
    font-size: 12px;
    color: #b2eaff;
    margin-left: 4px;
    opacity: 0.8;
  }

  .arpe-top-right-gauges {
    display: flex;
    align-items: center;
    gap: 1vw;
    margin-left: auto;
  }

  .arpe-gauge-img {
    width: 7vw;
    min-width: 70px;
    height: 6.5vw;
    min-height: 65px;
    display: block;
  }

  .arpe-gauge-label {
    margin-top: 2px;
    font-size: 13px;
    color: #b2eaff;
    text-align: center;
    letter-spacing: 1px;
    text-shadow:
      0 0 4px #0ff,
      0 0 2px #000;
    line-height: 1.1;
  }

  .arpe-main-layout {
    display: flex;
    flex-direction: column;
    height: 100vh;
    min-height: 0;
  }

  .arpe-content {
    flex: none;
    gap: 0.8vw;
    margin-top: 2vh;
  }

  .arpe-row-custom-top {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    min-height: 44px;
    background: transparent;
    gap: 1vw;
    margin-bottom: 8px;
  }

  .arpe-alert-box {
    flex: 1 1 0;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 1.08vw;
    font-weight: bold;
    border-radius: 0;
    box-shadow:
      0 0 16px 2px rgba(0, 246, 255, 0.08),
      0 0 8px 0 rgba(0, 246, 255, 0.12) inset;
    border: 1.5px solid rgba(0, 246, 255, 0.18);
    margin: 0;
    transition: none;
    backdrop-filter: blur(2px);
    opacity: 0.97;
    letter-spacing: 1px;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    position: relative;
  }
  .arpe-alert-box-left {
    background: linear-gradient(90deg, rgba(0, 234, 255, 0.18) 0%, rgba(0, 234, 255, 0.08) 100%);
    color: #00eaff;
    border-color: #00eaff99;
    text-shadow:
      0 0 8px #00eaff,
      0 0 2px #fff;
  }
  .arpe-alert-box-middle {
    background: linear-gradient(90deg, rgba(255, 255, 0, 0.18) 0%, rgba(255, 255, 0, 0.08) 100%);
    color: #ffe066;
    border-color: #ffe06699;
    text-shadow:
      0 0 8px #ffe066,
      0 0 2px #fff;
  }
  .arpe-alert-box-right {
    background: linear-gradient(90deg, rgba(255, 77, 79, 0.18) 0%, rgba(255, 77, 79, 0.08) 100%);
    color: #ff4d4f;
    border-color: #ff4d4f99;
    text-shadow:
      0 0 8px #ff4d4f,
      0 0 2px #fff;
  }
  .arpe-alert-box .alert-icon {
    margin-right: 8px;
    font-size: 1.2em;
    filter: drop-shadow(0 0 4px #00eaff88);
  }

  .arpe-table-content-bottom {
    position: absolute;
    left: 50%;
    top: -90px; /* 可根据实际表格高度微调 */
    transform: translateX(-50%);
    min-width: 350px;
    max-width: 90vw;
    background: rgba(28, 58, 99, 0.98);
    border-radius: 0.6vw;
    box-shadow: 0 0 30px rgba(11, 93, 209, 0.4);
    z-index: 9999;
    pointer-events: auto;
    padding: 10px 16px;
    opacity: 1;
    visibility: visible;
    transition:
      opacity 0.25s cubic-bezier(0.4, 2, 0.6, 1),
      visibility 0.25s;
  }

  .fade-table-enter-active,
  .fade-table-leave-active {
    transition:
      opacity 0.25s cubic-bezier(0.4, 2, 0.6, 1),
      visibility 0.25s;
  }

  .fade-table-enter-from,
  .fade-table-leave-to {
    opacity: 0;
    visibility: hidden;
  }

  .fade-table-enter-to,
  .fade-table-leave-from {
    opacity: 1;
    visibility: visible;
  }

  .arpe-top-col {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .arpe-top-col-left {
    justify-content: flex-start;
  }

  .arpe-top-col-center {
    justify-content: center;
  }

  .arpe-top-col-right {
    justify-content: flex-end;
  }

  .arpe-gauge-img-label-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .arpe-svg-fullrow {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
  }

  .arpe-row-temp-bars {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    margin: 0.5vw 0 0.5vw 0;
    min-height: 90px;
    height: 90px;
  }
  .arpe-temp-bar-group {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: flex-end;
    gap: 48px;
  }
  .arpe-temp-bar-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
  }
  .arpe-temp-bar-label {
    color: #00cfff;
    font-size: 18px;
    margin-bottom: 6px;
  }
  .arpe-temp-bar-outer {
    width: 22px;
    height: 70px;
    background: #183272;
    border-radius: 12px;
    position: relative;
    overflow: hidden;
    margin-bottom: 6px;
    border: 2px solid #00cfff;
    display: flex;
    align-items: flex-end;
  }
  .arpe-temp-bar-inner {
    width: 100%;
    background: linear-gradient(180deg, #00f6ff 0%, #00cfff 100%);
    border-radius: 10px 10px 0 0;
    position: absolute;
    bottom: 0;
    left: 0;
    transition: height 0.5s;
  }
  .arpe-temp-bar-value {
    color: #8ecfff;
    font-size: 18px;
    margin-top: 2px;
  }

  .arpe-temp-bar-group-inline {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    gap: 32px;
    margin-left: 32px;
  }
  .arpe-temp-bar-item-inline {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
  }
  .arpe-temp-bar-label-inline {
    color: #00cfff;
    font-size: 16px;
    margin-bottom: 4px;
  }
  .arpe-temp-bar-outer-inline {
    width: 28px;
    height: 60px;
    background: #183272;
    border-radius: 0;
    position: relative;
    overflow: hidden;
    margin-bottom: 4px;
    border: 2px solid #00cfff;
    display: flex;
    align-items: flex-end;
  }
  .arpe-temp-bar-inner-inline {
    width: 100%;
    background: linear-gradient(180deg, #00f6ff 0%, #00cfff 100%);
    border-radius: 0;
    position: absolute;
    bottom: 0;
    left: 0;
    transition: height 0.5s;
  }
  .arpe-temp-bar-value-inline {
    color: #8ecfff;
    font-size: 16px;
    margin-top: 2px;
  }

  .arpe-row-top-temp-center {
    justify-content: center;
    align-items: flex-end;
    gap: 24px;
  }
  .arpe-temp-bar-group-center {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    justify-content: center;
    gap: 60px;
    margin: 0 18px 0 18px;
  }

  .arpe-ds-card {
    min-width: 150px;
    max-height: 80px;
    background: rgba(10, 24, 48, 0.92);
    border-radius: 10px;
    box-shadow: 0 0 12px #00f6ff44;
    padding: 14px 18px 10px 18px;
    margin-right: 32px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    position: relative;
    z-index: 2;
  }
  .arpe-ds-row {
    color: #fff;
    font-size: 18px;
    margin-bottom: 6px;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 12px;
  }
  .arpe-ds-label {
    color: #b2eaff;
    font-size: 16px;
    margin-right: 8px;
  }
  .arpe-ds-value {
    color: #fff;
    font-size: 18px;
    font-weight: bold;
  }
  .arpe-ds-btn-row {
    margin-top: 8px;
    display: flex;
    flex-direction: row;
    gap: 8px;
  }
  .arpe-ds-btn {
    border: none;
    outline: none;
    border-radius: 4px;
    padding: 2px 14px;
    font-size: 15px;
    font-weight: bold;
    color: #fff;
    cursor: pointer;
    background: #2a5caa;
    transition: background 0.2s;
  }
  .arpe-ds-btn-open {
    background: #d64444;
  }
  .arpe-ds-btn-relax {
    background: #3a8bff;
  }
  .arpe-ds-btn-closed {
    background: #444;
  }

  /* 右侧卡片样式微调 */
  .arpe-ds-card-right {
    margin-left: 18px;
    margin-right: 0;
  }

  /* 设定/实测卡片居中样式 */
  .arpe-ds-card-center {
    margin: 0 18px;
  }

  /* 缩小按钮尺寸 */
  .arpe-ds-btn-row-small {
    gap: 6px;
    margin-top: 6px;
  }

  .arpe-ds-btn-small {
    padding: 1px 10px;
    font-size: 13px;
  }

  .arpe-ai-set-value-box {
    border: 1px solid #ff0000;
    color: #fff;
    padding: 4px 8px;
    margin-bottom: 8px;
    border-radius: 4px;
    font-size: 14px;
    text-align: center;
    background: rgba(255, 0, 0, 0.1);
    min-width: 120px;
  }

  /* 状态样式类 */
  .status-normal {
    color: #52c41a;
    font-weight: bold;
    text-shadow: 0 0 4px #52c41a;
  }

  .status-error {
    color: #ff4d4f;
    font-weight: bold;
    text-shadow: 0 0 4px #ff4d4f;
  }

  .status-warning {
    color: #faad14;
    font-weight: bold;
    text-shadow: 0 0 4px #faad14;
  }

  /* 表格容器样式 */
  .arpe-table-container {
    width: 16.2%;
    min-width: 280px;
    flex-shrink: 0;
    background-color: rgba(28, 58, 99, 0.7);
    border: 1px solid rgba(90, 130, 190, 0.4);
    box-shadow: 0 0 15px rgba(11, 93, 209, 0.2);
    border-radius: 8px;
    overflow: hidden;
  }

  .arpe-table-content {
    padding: 0;
    background: transparent;
  }

  .coilInfo {
    width: 100%;
    display: flex;
    // justify-content: space-between;
    // grid-template-columns: 1fr 1fr 1fr; /* 三等分 */

    :deep(.el-table) {
      background-color: transparent !important;
      --el-table-border: none;
      --el-table-row-hover-bg-color: unset;
      color: white;
    }

    :deep(.el-table th),
    :deep(.el-table tr),
    :deep(.el-table td) {
      background-color: transparent;
    }

    :deep(.el-table__inner-wrapper::before) {
      left: 0;
      bottom: 0;
      width: 100%;
      height: 0;
    }
  }

  .arpe-bar-rect-animated {
    transition:
      background 0.4s,
      box-shadow 0.4s;
    background: linear-gradient(90deg, #00eaff 0%, #3a8bff 100%);
    border-radius: 12px;
    box-shadow: 0 0 12px 2px #00eaff44;
    min-width: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .arpe-bar-rect-merged {
    transition:
      background 0.4s,
      box-shadow 0.4s;
    background: linear-gradient(90deg, #00eaff77 0%, #3a8bff77 100%);
    border-radius: 0;
    box-shadow: none;
    min-width: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.78;
    backdrop-filter: blur(2px);
  }

  .arpe-table-scroll-x {
    overflow-x: auto;
    width: 100%;
    padding-bottom: 6px;
    /* Firefox */
    scrollbar-color: #00eaff #0f2142;
    scrollbar-width: thick;
  }
  .arpe-table-scroll-x::-webkit-scrollbar {
    height: 16px;
  }
  .arpe-table-scroll-x::-webkit-scrollbar-track {
    background: #0f2142;
    border-radius: 8px;
  }
  .arpe-table-scroll-x::-webkit-scrollbar-thumb {
    background: linear-gradient(90deg, #00eaff 0%, #4ecfff 100%);
    border-radius: 8px;
    border: 2px solid #183272;
    min-width: 40px;
  }
  .arpe-table-scroll-x::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(90deg, #4ecfff 0%, #00eaff 100%);
    border: 2px solid #00eaff;
  }

  .coilno-card {
    position: absolute;
    right: 40px;
    width: 150px;
    min-height: 32px;
    background: linear-gradient(135deg, rgba(0, 234, 255, 0.18) 0%, rgba(0, 234, 255, 0.08) 100%);
    color: #00eaff;
    border: 2px solid #00eaff99;
    border-radius: 10px;
    box-shadow:
      0 0 12px #00eaff33,
      0 0 8px #0ff2;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: bold;
    z-index: 1000;
    letter-spacing: 1px;
    text-shadow:
      0 0 8px #00eaff,
      0 0 2px #fff;
    padding: 6px 0;
  }
  .coilno-card-1 {
    top: 80px;
    right: -20px;
  }
  .coilno-card-2 {
    top: 160px;
    right: -20px;
  }

  /* 时序跟踪图表卷号显示样式 */
  .arpe-chart-coilno {
    position: absolute;
    top: 256px; /* 显示在标题下方 */
    left: 50%;
    transform: translateX(-50%);
    background: linear-gradient(135deg, rgba(0, 234, 255, 0.15) 0%, rgba(0, 234, 255, 0.05) 100%);
    color: #00eaff;
    border: 1px solid #00eaff66;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 14px;
    font-weight: bold;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 140px;
    z-index: 10;
    text-shadow: 0 0 4px #00eaff;
    box-shadow: 0 0 8px rgba(0, 234, 255, 0.2);
  }

  /* 辊位图弹窗样式（强制应用蓝色主题） */
  :deep(.el-dialog.roll-details-dialog) {
    /* 覆盖 Element Plus 变量与直接背景，防止被默认白底覆盖 */
    --el-dialog-bg-color: rgba(10, 24, 48, 0.98);
    --el-bg-color-overlay: rgba(10, 24, 48, 0.98);
    background-color: rgba(10, 24, 48, 0.98) !important;
    border: 2px solid #00f6ff;
    border-radius: 16px;
    box-shadow:
      0 0 40px rgba(0, 246, 255, 0.4),
      inset 0 0 20px rgba(0, 246, 255, 0.1);
    backdrop-filter: blur(15px);
  }

  :deep(.el-dialog.roll-details-dialog .el-dialog__header) {
    background: linear-gradient(135deg, rgba(0, 246, 255, 0.15) 0%, rgba(0, 180, 255, 0.08) 100%);
    border-bottom: 2px solid rgba(0, 246, 255, 0.4);
    border-radius: 16px 16px 0 0;
    padding: 25px 30px;
    position: relative;
  }

  :deep(.el-dialog.roll-details-dialog .el-dialog__title) {
    color: #00f6ff;
    font-size: 22px;
    font-weight: bold;
    text-shadow: 0 0 12px #00f6ff;
    letter-spacing: 1px;
  }

  :deep(.el-dialog.roll-details-dialog .el-dialog__body) {
    padding: 30px;
    background: transparent !important;
  }

  :deep(.el-dialog.roll-details-dialog .el-dialog__headerbtn .el-dialog__close) {
    color: #00f6ff;
    font-size: 24px;
    transition: all 0.3s ease;
  }

  :deep(.el-dialog.roll-details-dialog .el-dialog__headerbtn .el-dialog__close:hover) {
    color: #4ecfff;
    transform: scale(1.1);
    text-shadow: 0 0 8px #4ecfff;
  }

  /* 统一内部容器蓝色卡面风格，避免出现白底 */
  :deep(.el-dialog.roll-details-dialog .image-wrap) {
    background-color: rgba(28, 58, 99, 0.7);
    border: 1px solid rgba(90, 130, 190, 0.4);
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(11, 93, 209, 0.15);
    padding-top: 8px;
  }

  :deep(.el-dialog) {
    background: rgba(36, 128, 255, 0.7) !important;
  }

  /* 覆盖 Element Plus 对话框背景：注意自定义 class 加在 .el-overlay-dialog 上 */
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog) {
    background: rgba(10, 24, 48, 0.98) !important;
    border: 2px solid #00f6ff;
    border-radius: 16px;
    box-shadow:
      0 0 40px rgba(0, 246, 255, 0.4),
      inset 0 0 20px rgba(0, 246, 255, 0.1);
    backdrop-filter: blur(15px);
  }
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog__header) {
    background: linear-gradient(135deg, rgba(0, 246, 255, 0.15) 0%, rgba(0, 180, 255, 0.08) 100%);
    border-bottom: 2px solid rgba(0, 246, 255, 0.4);
    border-radius: 16px 16px 0 0;
    padding: 20px 26px;
  }
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog__title) {
    color: #00f6ff;
    font-size: 20px;
    font-weight: 700;
    text-shadow: 0 0 10px #00f6ff;
    letter-spacing: 1px;
  }
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog__body) {
    background: transparent !important;
    padding: 20px 26px;
  }
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog__headerbtn .el-dialog__close) {
    color: #00f6ff;
    font-size: 22px;
  }
  :deep(.el-overlay-dialog.roll-details-dialog .el-dialog__headerbtn .el-dialog__close:hover) {
    color: #4ecfff;
    text-shadow: 0 0 8px #4ecfff;
  }
  /* 蒙层颜色（可选） */
  :deep(.el-overlay .roll-details-mask) {
    background-color: rgba(0, 10, 20, 0.46);
    backdrop-filter: blur(2px);
  }
  /* 内部卡面统一蓝色基调，避免白底 */
  :deep(.el-overlay-dialog.roll-details-dialog .image-wrap) {
    background-color: rgba(28, 58, 99, 0.7);
    border: 1px solid rgba(90, 130, 190, 0.4);
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(11, 93, 209, 0.15);
  }

  /* 新增：生产效率监控图表样式 */
  .arpe-production-efficiency-chart {
    flex: 1;
    min-width: 300px;
    height: 250px;
    background: rgba(0, 24, 48, 0.22);
    border: 1px solid rgba(0, 246, 255, 0.2);
    border-radius: 8px;
    padding: 12px;
    margin-right: 8px;
    box-shadow: 0 0 12px rgba(0, 246, 255, 0.12);
    display: flex;
    flex-direction: column;
  }

  .chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
    min-height: 24px;
  }

  .chart-legend {
    display: flex;
    gap: 12px;
    font-size: 11px;
    color: #ffffff;
    flex-wrap: wrap;
  }

  .chart-title-left {
    color: #00f6ff;
    font-weight: 700;
    font-size: 14px;
    text-shadow: 0 0 8px rgba(0, 246, 255, 0.8);
  }

  .legend-item {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
  }

  .legend-dot-power {
    background-color: #40bfff;
  }
  .legend-dot-torque {
    background-color: #a97af8;
  }

  .production-efficiency-chart__container {
    width: 100%;
    height: 220px;
    flex: 1;
  }

  /* 调整底部图表行的布局 */
  .arpe-row-bottom-graph {
    display: flex;
    gap: 8px;
    align-items: stretch;
  }
</style>
